18 December 2010

Can't SSH to Amazon Elastic Compute Cloud (EC2) Instance

I've decided that I'm going to learn about Amazon Elastic Compute Cloud (EC2) over this Holiday break.  I've read a few articles, listened to a few podcasts so I have an idea what it's about, just haven't actually gone thru the motions myself.

What am I going to do with a virtual machine (VM) in the cloud?  Not much quite yet.  I have some ideas but first need to figure out how things work.

So on Friday night I signed up for an EC2 account and started to follow the Getting Started Guide on the Amazon site.  As usual, things went smooth for the first few minutes but as usual, progress came to an immediate screeching.

I started an plain vanilla Basic 64-bit Amazon Linux Amazon Machine Image (AMI) just to get things going and verify that I could SSH into the thing per the getting started guide.  But when I SSH'd, nothing, nada, zip.  Timeout.


This darn thing acts like it's not running.  I started, restarted, used different AMI, mucked with security group setting without any progress.  I even edited the default security group to open the thing wide open:


Still nothing.  Did the google thing to see what other people are doing and came across a few hits in the Amazon Web Services forums where people are claiming the the web services aren't starting up correctly in the US-East zone.  Hey, that's me!  Ok, I'm not stupid, its just some tech problem.  I'll take a break and try it again in a few hours.

Few hours later:  nothing, nada, zip.  Ok, I am stupid.  I can't even log into a stupid instance.  I probably started/stopped an EC2 AMI 10 times but can't do anything with it.  This new thing I've learned is frickin' amazing.

And as usual, as soon as I've convinced myself that all hope is lost, ding.  Wait, doesn't my Westell DSL modem block SSH?  Oh, frick of course it does.  Damn it so, the last 3-4 hours of trouble was caused by my own firewall??

Of course it was.  I really hate this Verizon provided modem and keep telling myself that I'm going to buy a different one.  But this is free and I'm cheap.  So I'll keep shooting myself in the foot and someday get smarter and dump this junk.

In the Firewall->Port Forwarding menu, I just added the SSH service to a dynamic host.


And now when I launch a new instance, I get this:


Amazing.  Only hours and hours of work to launch and connect.  Let the fun begin.

What do you think? Leave a comment.

29 November 2010

Working with the 90 Character Limit of Twitter

What?  Twitter has a 90 character limit?  No, it's 140.  Everyone knows that.

Mr Wikipedia says this about SMS length

"... resources in the system could be used to transport messages at minimal cost. However, it was necessary to limit the length of the messages to 128 bytes (later improved to 140 bytes, or 160 seven-bit characters) so that the messages could fit into the existing signaling formats."

Using the Groovy code that I did the other day to send a text message via a twitter Direct Message, if the message length is greater than 140 characters, twitter complains with this error:

403:The request is understood, but it has been refused.  An accompanying error message will explain why.
{"request":"\/1\/direct_messages\/new.json","error":"The text of your direct message is over 140 characters."}
TwitterException{exceptionCode=[6bcd7469-01bff100], statusCode=403, retryAfter=0, rateLimitStatus=null, version=2.1.7}


That kinda says that I can send 140 characters, so what's this nonsense about a 90 character limit?

Well, true, you can send 140 characters but if you're hacking the system for the purposes of having Twitter forward your message as a text message to a phone then different rules apply.

Take a look at what happens when you send a Direct Message of 140 characters to an account that is set up to send a txt:
String message = "12345678911234567892123456789312345678941234567895" +
                 "12345678961234567897123456789812345678991234567891" +
                 "1234567891123456789212345678931234567894"

DirectMessage directMessage = twitter.sendDirectMessage(screenName, message)
Twitter breaks the message into 2 separate texts (and my phone occasionally gets the 2nd text first).

For the app that I'm working on, I need my data in a single text message, I don't want the mess of re-assembling.

I think the message split is because a header of:

"Direct from" screen name:

and a footer of

"Reply with 'd" screen name "hi.'"

is added to each message.

I've found that the amount of data that you can actually send depends on the screen name.  Since screen names can be up to 15 chars, you lose:

Header:
Direct from screenname:
= up to 28 characters (12 + screen name)

Footer:
Reply with 'd screenname hi.'
= up to 34 characters (19 + screen name)

140 - 28 - 34 = 78

Uh, 78 is not 90.  What the heck? I guess my math has errors.

But check this out.  By adjusting my direct message, I find that a 90 character message is the sweet spot for a 15 character screen name and the message is sent as a single text.  91 characters will cause the message to be split over 2 texts.

Maybe that header and footer isn't as big as I think it is.

140 - 90 = 50 characters for header/footer?

If a screen name is used twice (2 * 15 = 30), then maybe the bloat is only 20 characters?


What happens if I send messages to a different screen name, one that is smaller than 15 characters?

What is I use a screen name of 8 characters?  Should I be able to send a message of

140 - 20 (bloat) - (2 * 8) = 104 characters?

After a quick reassignment of my phone to a different twitter account, I tried a test with a screen name that is 8 characters.  Could I send 104?  Durn right I could!  And I could also send 109.  But 110 would cause a message split.  So I have an extra 5 characters unaccounted  for.

What happens if I send to a ...  No, this is going on too long. 

The max screen name is 15 characters and that limits the max amount of data that can be sent in one message to 90 characters.

If the screen name is less than 15 characters, then you get 90 plus some extra.  YMMV


What do you think? Leave a comment.

27 November 2010

Send SMS Text Message from Java/Groovy - via Twitter

Writing code to send an SMS text message is fairly easy on a smart phone like an Android.  But from a desktop, sending texts is still a mess, not always free, and/or requires a phone connected to your server.

I simply want to send a message to my phone when my app receives some data.  I don't need a complex library with lots of setup nor do I want to sign up for a pay service.

Now this isn't the cleanest solution to text from an app but Twitter can send messages to your phone when people you follow update their status, when someone mentions or replies to you, or when you get a direct message.

My last two write-ups, "Send a Simple Tweet with OAuth and Groovy" and "Send a Direct Message Tweet with Groovy" showed how easy it is to use Java/Groovy and the Twitter4J library to send messages to your own Twitter account or a message to anyone else.

By sending a tweet to an account that you follow or a Direct Message to your own account, Twitter can be setup to forward that message to a phone that you associate with your account.

Simply go to your Twitter account, Settings, Mobile and follow the easy instruction. Then use one of the sample apps from my previous posts and tweet-text away!

Note:
  • This only allows you to tweet-text to phones that have been setup to follow accounts. 
  • This does not allow you to send a text to a cell phone not registered with Twitter.
  • This works for what I need.
  • Do you know a better/easier, free method?  Write a comment!


What do you think? Leave a comment.

Send a Direct Message Tweet with Groovy

Alright.  Using the Twitter4J library and Groovy, I've beaten down the OAuth beast and have a simple example app to send a "update status" tweet.

Now instead of sending a message to my own account, let's do a real easy mod to send a Direct Message to a specific user   Using the same app as before, the only changes needed are:

  • import DirectMessage
  • change from twitter.updateStatus(message) to twitter.sendDirectMessage(screenName, message)
import twitter4j.DirectMessage;
import twitter4j.Twitter
import twitter4j.TwitterFactory
import twitter4j.Status
import twitter4j.http.AccessToken
import twitter4j.http.RequestToken
import java.io.BufferedReader
import com.thoughtworks.xstream.XStream

try{

   Twitter twitter = new TwitterFactory().getInstance();

   // set key and secret that you get from Twitter app registeration at:
   //     http://dev.twitter.com/pages/auth#register
   twitter.setOAuthConsumer("Your Consumer key", "Your Consumer secret");

   // load access token if it exists
   AccessToken accessToken = null
   def tokenFile = new File("accessToken.xml")

   if (tokenFile.exists()) {
      def xstream = new XStream()
      tokenFile.withInputStream { ins -> accessToken = xstream.fromXML(ins) }
      twitter.setOAuthAccessToken(accessToken)
   } 

   else {

     // get the URL to request access to Twitter acct
     RequestToken requestToken = twitter.getOAuthRequestToken();
     String authUrl = requestToken.getAuthorizationURL()
     System.out.println("Open the following URL and grant access to your account:");
     System.out.println(authUrl);

     // take the PIN and get access token
     System.out.print("Enter the PIN:");
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     String pin = ""
     pin = br.readLine();
     accessToken = twitter.getOAuthAccessToken(requestToken, pin);

     // persist token
     def xstream = new XStream()
     xstream.classLoader = getClass().classLoader
     new File("accessToken.xml").withOutputStream { out -> xstream.toXML(accessToken, out) }
   }

   String message = "from Groovy w/ token" + accessToken.getToken()
   String screenName ="ScreenNameToSendTo"

   DirectMessage directMessage = twitter.sendDirectMessage(screenName, message)
   System.out.println("Direct message sent to " + directMessage.getRecipientScreenName());

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

What do you think? Leave a comment.

Sending a Simple Tweet with OAuth and Java/Groovy

Come on, man!  What used to a be a simple task to send a tweet is now a OAuth nightmare.

A year or so ago, I built that tweet-a-w/e thing that sniffed XBee chirps and sent them to a twitter account that kindly routed them to my cell phone.

I have a need now to receive an XML stream, parse out a few tidbits and then send the results out as a SMS text message.  Remembering that tweet-a-w/e app, I thought that I would again leverage Twitter to send the text message.  All I need to do is send a tweet via a Twitter API and have my account set up to send the content to a phone number.

This time my XML receiver is in Java/Groovy, so I grabbed the latest Twitter4J, glanced at the UpdateStatus example and tried a quick test with Groovy.
import twitter4j.Twitter  
import twitter4j.TwitterFactory  
import twitter4j.Status  
    
Twitter twitter = new TwitterFactory().getInstance("myAcct","myPassword");  
Status status = twitter.updateStatus("from Groovy");  
System.out.println("Successfully updated the status to [" + status.getText() + "].");  
Did that work?  Of course not.  Authentication FAIL.

Caught: 401:Authentication credentials were missing or incorrect.
{"errors":[{"code":53,"message":"Basic authentication is not supported"}]}
TwitterException{exceptionCode=[15bb6564-00e5bee0], statusCode=401, retryAfter=0, rateLimitStatus=null, version=2.1.7}

What the heck?  Basic Authentication is not supported?  Darn it, what is this stupid OAuth thing about?  Here's the Twitter page "Authenticating Requests with OAuth" that looks real interesting to read.  Arghhhhh.  I just want to send a flippin' tweet, I really don't have time to research this at Hueniverse.

After some more quick Googling, this isn't as bad as it first looks.It boils down to getting a key and secret pair.  The steps are:
  • Goto Twitter and register your app.
  • You'll get a consumer key and secret which are similar to the public and private keys used in protocols such as ssh. 
  • Use the key and secret to sign every request you make to the Twitter API
import twitter4j.Twitter  
import twitter4j.Twitter
import twitter4j.TwitterFactory
import twitter4j.Status
import twitter4j.http.AccessToken
import twitter4j.http.RequestToken
import java.io.BufferedReader

try{

   Twitter twitter = new TwitterFactory().getInstance();

   // set key and secret that you get from Twitter app registeration at:
   //     http://dev.twitter.com/pages/auth#register
   twitter.setOAuthConsumer("Your Consumer key", "Your Consumer secret");

   // get the URL to request access to Twitter acct
   RequestToken requestToken = twitter.getOAuthRequestToken();
   String authUrl = requestToken.getAuthorizationURL()
   System.out.println("Open the following URL and grant access to your account:");
   System.out.println(authUrl);

   // take the PIN and get access token
   System.out.print("Enter the PIN:");
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   String pin = ""
   pin = br.readLine();
   AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, pin);

   String message = "from Groovy w/ pin" + pin
   Status status = twitter.updateStatus(message);
   System.out.println("Successfully sent " + message);

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

Ok, so that works.  But every time you run the program, you need to go and fetch the darn token.  According to Twitter, the token doesn't expire, so let's persist the thing.

I like using XStream to serialize Java/Groovy objects to/from XML.  A quick update to the code above lets us save an XML file that we can reload as needed.
import twitter4j.Twitter
import twitter4j.TwitterFactory
import twitter4j.Status
import twitter4j.http.AccessToken
import twitter4j.http.RequestToken
import java.io.BufferedReader
import com.thoughtworks.xstream.XStream

try{

   Twitter twitter = new TwitterFactory().getInstance();

   // set key and secret that you get from Twitter app registeration at:
   //     http://dev.twitter.com/pages/auth#register
   twitter.setOAuthConsumer("Your Consumer key", "Your Consumer secret");

   // load access token if it exists
   AccessToken accessToken = null
   def tokenFile = new File("accessToken.xml")

   if (tokenFile.exists()) {
      def xstream = new XStream()
      tokenFile.withInputStream { ins -> accessToken = xstream.fromXML(ins) }
      twitter.setOAuthAccessToken(accessToken)
   } 

   else {

     // get the URL to request access to Twitter acct
     RequestToken requestToken = twitter.getOAuthRequestToken();
     String authUrl = requestToken.getAuthorizationURL()
     System.out.println("Open the following URL and grant access to your account:");
     System.out.println(authUrl);

     // take the PIN and get access token
     System.out.print("Enter the PIN:");
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     String pin = ""
     pin = br.readLine();
     accessToken = twitter.getOAuthAccessToken(requestToken, pin);

     // persist token
     def xstream = new XStream()
     xstream.classLoader = getClass().classLoader
     new File("accessToken.xml").withOutputStream { out -> xstream.toXML(accessToken, out) }
   }

   String message = "from Groovy w/ token" + accessToken.getToken()
   Status status = twitter.updateStatus(message);
   System.out.println("Successfully sent " + message);

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

The serialized Access Token looks like this:


  5555555-AbCdEF
  1oKiOlOlOlOl
  
    oauth_token=5555555-AbCdEF
    oauth_token_secret=1oKiOlOlOlOl
    user_id=007
    screen_name=bond

  
  bond
  007

Notes:

For the above examples, I used:
  • Groovy Version: 1.7.0 JVM: 1.6.0_22
  • Twitter4J 2.1.7  For this, I copied only the twitter4j-core-2.1.7.jar into the Groovy lib folder.  On Linux, this is /usr/share/Groovy/lib
  • XStream 1.3.1  For this, I copied the xstream-1.3.1.jar and xpp3_min-1.1.4c.jar into the Groovy lib
What do you think? Leave a comment.

13 August 2010

Sad Day for the Great White Boxster

After a little more than a year of ownership and the main reason that I haven't been updating my blog, I sold my Boxster (the Great White). She was a good car but after buying a 911 in early Spring, I just wasn't driving her much.

My family is much sadder than me though cause they liked the Boxster better than the 911.

I really love the mid-engine Boxster and will probably buy a Cayman S in the near future.  After getting the Porsche bug, I wasn't happy until I had a 911.  What a complete different experience.  The Boxster is refined and hugs the curves like no other car I ever driven.  The 911 is raw, loud and dares you to give it too much gas so it can swing its ass around and make you look like a noob driver.  But it's so fast and the power is addicting.

09 August 2010

Sanyo DP26648 White Screen of Death

 Santa brought my game player son a Sanyo SP2664 26-inch Widescreen LCD HD Television last Christmas.  A few months into the year, the TV started getting occasional white lines diagonally across the screen, the greens looked weird, and then the audio went in/out.  I could've/should've hauled it back to Wally Mart but grumbled about it and did nothing.

We came home from our July 4th vacation and the darn TV is dead.  White Screen of death.  No sound, just a stupid looking white screen.

An interesting thread on the Electronics Repair Google Group led my son and I to think that we could fix this beast.

According to the thread, "it has been reported that there is a defective ribbon cable that causes this problem".  And the possible fix is "Clean glue like material from spaced further apart trace of FFC ribbon or replace the ribbon wire P/N: N6CD FFC".

Well, I'm pleased to report that we hacked and smashed and tore that darn TV up, finally got to the elusive cable.  And it looks nothing like that picture.  Our cable looked fine, no glue, seemed like a good connection.  And the TV remains broken and in 300-bazillion parts.

We had fun exploring the TV but it would have been a better story if the darn thing would have actually been easy to fix.  I think our TV had more wrong with it than just the cable.  But if your TV is showing the white screen of death, read the link and good luck.