Wednesday, June 19, 2013

Raspberry Pi Powered, Android Controlled, Tomcat Serviced, Remote Garage Door Opener (Whew!)

A few months ago I had left for a business trip and couldn't remember if I had closed the garage door.  Nearly all of us have done this at one point in our lives.  I promised myself this would never happen again, and a new project was spawned!


Project Overview

While some plug and play solutions exist such as the Liftmaster 828LM, I wanted to make my own out of curiosity.

The project consists of two components, both of which are entirely open source:
  • An Android application which posts commands to a web service.  The Android application retrieves an authorization token from Google and sends it along with the requested command.
  • The web service which listens for commands and credentials.  These credentials are posted to Google to verify they are authentic.  Once the user is verified, the command is executed.

I will be giving an overview of the project, but it is by no means a step-by-step tutorial.  There have been similar projects online, but I couldn't find any with detailed code on both sides (client + server).  This should be a good reference for anyone who wants to do things like:

  • Run Tomcat on their Raspberry Pi
  • Authenticate users with Google's OAuth 2 (both getting the token and authenticating the token)
  • Interact with the GPIO pins of the Raspberry Pi directly in Java
  • See how a basic Service to Activity (interaction / communication) model can look like in Android.  I find this to be one of the most common questions asked by new developers

Demonstration:


This is a quick video of the whole project in use.  Note the status of the door is stated on the home screen of the application so there is never any doubt whether it is open or closed!




Hardware

  • Raspberry Pi Model B  - It can act as the web service and physically interface with the garage door all in one device (rather than purchasing something like an Arduino, which would need a more powerful computer sitting in front of it to run the web service).  Less is more.
  • Edimax EW-7811Un USB Wi-Fi N Dongle - Since I don't have CAT6 run out to my garage door opener (yet), I had to accept using Wi-Fi which I generally avoid at all costs.  The chipset in this dongle (RTL8188CUS) is compatible right out of the box with the Raspberry Pi.
  • Magnetic Switch - This is to determine whether the garage is opened or closed.  This particular switch is fantastic for one reason; depending on which contact points you hook up to, it can be made either normally open or normally closed.
  • Sainsmart Relay Module - Great little board that has relay isolation components already built into it.  Separates the power supply from the signal with an optocoupler which protects your other components when the coil's magnetic field collapses.
  • Resistors - Miscellaneous resistors.  Supplied link is a great pack that gives you a little bit of everything for home projects.
  • Wiring of your choice.

Design requirements

  • Control (toggle) the garage remotely, whether 5 feet away, or 5 countries away
  • Check the state of the garage door, without needing to toggle / close it
  • Do so from within an Android application
    • Use Google as the application's authenticator
    • Take advantage of Android's AccountManager
  • Be accessible via HTTP so it could be extended to any platform in the future such as iPhone, iPad, or a simple web browser
    • Run HTTPS so eavesdropping / replay attacks would not be possible
    • Use an unsigned TLS certificate.  There is no need to pay for one if you are the developer!
  • WAF needs to be high.
    • Low cost
    • Must not affect normal operation of the door
  • No pre-built solutions
    • Rarely demonstratively secure
    • Not extensible
    • Not fun =P



Web Service

The web service is responsible for listening for requests over the network.  This performs the following actions upon receiving a request:
  1. Authenticates the request with Google OAuth 2.0 with an subclass of RealmBase, GoogleRealm.
  2. Authorizes the user with a local file containing a line delineated list of valid users
  3. If there was a successful authentication and authorization, perform the required action, namely:
    • Toggle the garage
    • Get the state of the garage

Libraries Used

  1. Pi4J - Java bindings which allows interaction with the GPIO pins on the Raspberry Pi.  Being Tomcat is the web server, Pi4J was a perfect complement.
  2. json-simple - Java library which parses and extracts JSON messages.

Security

The application is protected with an implementation of a Realm.  This implementation is dubbed "GoogleRealm" and validates Google authorization tokens, as well as validates that the returned email account exists in a local file.  When Tomcat handles an HTTP request for a protected resource (defined in web.xml), it calls the overridden authenticate method inside of GoogleRealm method with two Strings.  These strings are passed in by the defined implementation of Authenticator, also defined inside web.xml.  An Authenticator's job in the scope of Tomcat is to take a Request and send the passed credentials to the defined Realm.  Making a custom Authenticator allows one to receive credentials from a request by any means.  In other words, it abstracts how credentials are retrieved in the request from how they are authenticated.

In this application, the BasicAuthenticator is used to retrieve credentials.  You may have been able to guess that BasicAuthenticator retrieves the username and password from HTTP basic access authentication.  The username field contains the Google authorization token and the password field contains a shared secret among all users.  The authorization token is requested with the scope oauth2:https://www.googleapis.com/auth/userinfo.email which, when posted to Google, allows the verifier to view the email address of the account that the authentication token is associated with.

I originally did not have this shared password in place but I soon realized that there was a security vulnerability in the application.  Any service that you authenticate with using your Google account could post its own authorization token to your garage door opener and open your garage.  In computer security, this is called the confused deputy problem.  This can be mitigated by requiring an additional secret with all authorized users.  With a shared secret, third party sites need an additional piece of information that only authorized users posses.

Once the user's request is authenticated it is then checked for authorization against a line delineated local file which has a list of email addresses allowed to interact with the application.  If that email exists, the proper Principal is then added to the request session and passed to servlet routing.

Garage Interface

The garage interface and GPIO control was the simplest part of the application, thanks to the Pi4j library.  All of the wiring below below, are the pinouts used for application inside of GarageDoorGPIO.  Note that Pi4J does not use pin numbers as their identifiers, and instead uses the more abstract method that WiringPi uses.

  • Toggling the garage
    • The garage door was fairly straight forward to interact with physically.  I had a wall mounted control which toggles the garage door when two wires are shorted together (this is the behavior of most any door).
    • When this module is activated, the garage is toggled.  This module is controlled via the following wires: (Note - make sure you know which revision of the Raspberry Pi you have as their pins have changed!)
      • 5V - Pin 02 on the Raspberry Pi diagram below (upper right pin) to label G on the relay diagram.  This powers the relay coil.
      • 3.3V - Pin 17 (fifth from the bottom, left row) to label F.  This provides 3.3V as a signal current to the relay.
      • 0V - Pin 25 to label E.  This grounds the 5V supply.  Note that the 5V and 0V are isolated via an optocoupler  from the 3.3V connection(The schematic can be found here.)
      • GPIO - Pin 11 (GPIO 17) to label B.  This is going to be configured as an OUTPUT pin, and set LOW, which will activate the relay.
      • The two top most screw-down relay holes (in the upper left) are what will be connected to each other when the relay triggers.  These two wires will need to be run to your garage door in a manufacturer / model dependent fashion.
  • Checking the garage state
    • This was accomplished with the magnetic switch listed above.  One half of the switch is connected to the swinging door, the other half is attached to the door frame.  In this case half of it was attached to the wall above the garage door, and half of it was attached to the garage door itself.  When the garage door is closed, these two halves are within about a 1/4 inch of each other.
    • Make a wire with an inline 1k ohm resistor (to prevent accidentally blowing out a GPIO pin).
      • 3.3V - Connect this wire from Pin 1 on the Raspberry Pi and connect it to one side of the magnetic switch mentioned above (red, or white wire in diagram below)
      • Connect a wire from the opposite side of the magnetic switch and run it to pin 12 (GPIO 18).
      • When the door is closed, this circuit should be closed.
This is the magnetic switch.  The front side (closest in this picture) is attached to the moving door, the rear side is screwed into the wall.  When they come within about 1/4 inch of each other, it toggles.



Sorry for the mediocre picture... it's mounted on top of the opener.

Android Application


Architecture:

The architecture of the application is very simple.  Clicking an action button in the UI triggers an IntentService to run.  These IntentService(s) are run in the background on a worker thread already, so we don't need to worry about spawning off threads on our own.  When the Service is completed, it fires off a broadcast.  If the main Activity is active at this point, a Toast is generated for the user which states what the result of their action was.

Overview:


The controller for this application is written for the Android platform.  This could have been a web application but I wanted to use the AccoutManager on Android so the setup was as seamless as possible to any end user (no need to enter account information).  The first time a user account is selected and an action button is clicked, an authorization prompt pops up for the user.  This allows the application to get a token which can prove the account's identity.



There are three interaction points in the application that this token is used for:
  • Toggle the garage (actuate the relay which in turns activates the door)
  • Close the the garage (toggles the garage if it is not in a closed state)
  • Display the status of the garage (open / closed)

Security:

The security of the Android application lies in its use of HTTPS.  I did not want to create my own domain and pay for a signed TLS certificate, so instead, I made an SSLSocketFactory factory (GarageSSLSocketFactory).  This is described in good detail here.  What this does is initialize the application's SSLContext to use your own default key store for acceptable certificates.  This includes your own self-signed certificates and allows you to have secure communication without the need for paying for a signed certificate, or doing something really, really, bad.  All you need is a dynamic DNS domain, assuming you do not have a reserved WAN IP address.

UI:

Main screen
Configuration Screen (accessible by hitting menu button)

Configuration

  1. Download the GarageWebService and GarageAndroid from Github.  (If you've downloaded it in the past, make sure you update your repository to fix a classpath error.
  1. On a spare computer (other than the RPi) install Eclipse for Java Developers
    1. Click Help -> Install new Software
    2. Select Work with Kepler - http://download.eclipse.org/releases/kepler
      1. Install Eclipse Java EE Developer Tools, Eclipse Java Web Developer Tools, JST Server Adapters, JST Server Adapters Extensions, then restart Eclipse
    3. New->Other->Web->Dynamic Web Project -- Name it GarageWebService
      1. Select target runtime if it already exists, or click new runtime if you don't have one.
      2. Click Apache Tomcat v7.0 - Check create new local server
      3. Click download and install (If you don't already have it)
      4. Close eclipse
    4. copy src + WebContent from downloaded GarageWebService and override the current src + WebContent in the workspace project (probably {homedir}/workspace/GarageWebService)
      1. Reopen eclipse, right click in the navigator pane on the left and click refresh
    5. Open GoogleRealm.java and change the password if desired.  This password protects your garage door from being used from another service that has some permission on your Google account (such as stackoverflow)
    6. Highlight the files GoogleRealm.java, GoogleUtil.java, and UserDAO.java
      1. Right click on one of the highlighted files-> export -> Java -> JAR file and name it GoogleAuth.jar
    7. Now right click on the project itself,  export -> Web -> war file and name it GarageDoor.war (important the name + case is exactly this)
  2. Install the Raspian distribution on your RPi, then enable SSH for terminal access.  We do not need a graphical interface
    1. Transfer GoogleAuth.war to the Rpi
    2. sudo apt-get update and sudo apt-get upgrade
    3. sudo apt-get install tomcat7 tomcat7-admin
      1. edit /etc/default/tomcat7 and change the following two variables
        1. TOMCAT7_USER=root
        2. JAVA_HOME=/usr/lib/jvm/jdk-7-oracle-armhf
    4. Change to a directory for downloading files (we will now be installing wiringPi)
    5. git clone git://git.drogon.net/wiringPi
      1. cd wiringPi
      2. git pull origin
      3. sudo ./build
    6. Now we'll add ourselves as a valid tomcat user
      1. sudo nano /etc/tomcat7/tomcat-users.xml
        1. Add the following line, right above the last line, </tomcat-users>
        2. <user username="ryanfx" password="asecretpassword" roles="manager-gui"/>
        3. Replace ryanfx and asecretpassword with whatever you'd like
    7. Generating an SSL certificate
      1. We will generate a certificate using RSA and name the store garagessl
        1. keytool -genkey -alias garage -keyalg RSA -keystore garagessl
        2. For the question "w
        3. hat is your first and last name?" 
        4. enter the external IP address or dyn-dns name that your RPi will be using eg. www.mydyndnsname.com
        5. Everything else can be blank, but enter y when it confirms that all the information is correct.
        6. Let it generate a new certificate for a few minutes, then hit enter when it asks you for a new password
        7. Change permissions and move it to someplace that tomcat can read it
          1. sudo chown root:tomcat7 garagessl
          2. sudo mv garagessl /etc/tomcat7
      2. Configure Tomcat to read the certificate
        1. sudo nano /etc/tomcat7/server.xml
        2. Copy the following below the connector element already active running on port 8080, and comment out the one running on port 8080

        3. <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
          maxThreads="150" scheme="https" secure="true"
          clientAuth="false" sslProtocol="TLS"
          keystoreFile="/etc/tomcat7/garagessl"
          keystorePass="thepasswordyouused" />
      3. We'll copy the GarageAuth jar to the Java library folder
        1. sudo mv GoogleAuth.jar /usr/share/java/
        2. Find the json simple jar inside the web service package you downloaded and move it as well.  We need to do this because security realm's use Tomcat's (Catalina's) classloader, not your webapp's.
          1. sudo mv json_simple-1.1.jar /usr/share/java/
        3. Create softlinks so tomcat has access to them
          1. cd /usr/share/tomcat7/lib/
          2. sudo ln -s ../../java/GoogleAuth.jar .
          3. sudo ln -s ../../java/json_simple-1.1.jar .
      4. Add users that will be able to authorize with your new service
        1. sudo nano /root/garage_users
        2. Add a single line to the file, whatever the gmail address is that you will be authenticating with.
      5. Restart Tomcat sudo /etc/init.d/tomcat7 restart
      6. Open a browser on the Eclipse machine and go to https://192.168.11.30:8443/ replacing the IP address with whatever IP address your Rpi has pulled.  
      7. You should get a "certificate untrusted" error.  If you've reached this point, everything is good!
      8. Upload the GarageDoor.war to the raspberry pi's Tomcat.  In this example, visit https://192.168.11.30:8443/manager/html
      9. Click start to start it
      10. Now we will get the public certificate the server is issuing and store it in PEM format.  Replace the IP address to whatever the RPi has.
        1. echo | openssl s_client -connect 192.168.11.30:8443 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem
      11. You now have the PEM encoded certificate of your server.  We will now download bouncy castle jars to generate a keystore (do not download past version 146 - Android will not play nice with anything newer)
      12. wget http://www.bouncycastle.org/download/bcprov-jdk15on-146.jar
      13. We will now generate the keystore (enter a password when prompted to protect your keystore and enter yes to trust this certificate)
        1. keytool -import -v -trustcacerts -alias 0 -file <(openssl x509 -in ./mycert.pem) -keystore mystore.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath ./bcprov-jdk15on-146.jar
      14. Copy mystore.bks to the machine which has eclipse
      15. Open eclipse
      16. Install android ADT (http://developer.android.com/sdk/installing/installing-adt.html)
      17. Import -> Android -> Existing Android Code Into Workspace
      18. Create a new folder called raw inside of the res folder
      19. Move your mystore.bks file into this new folder
      20. Change the password in GarageSSLSocketFactory.java to reflect the password used during the keytool command
      21. Right click the Project -> export -> Android -> Export Android Application
      22. Install the application to your phone
      23. Open the app, go to settings, fill in host / port / account information
      24. Fill in the server password (the one you wrote in GoogleRealm.java)
      25. You're done!

122 comments:

  1. Thanks for this. It's a great feeling to be able to accomplish these types of things. Have you considered commercializing this?

    ReplyDelete
  2. You're welcome! I decided that with several preexisting commercial implementations out there already, creating an open source project would be more beneficial.

    ReplyDelete
  3. I see that you took care of authentication (compared to other garage door projects with Rasps). How do you reach your home? I suppose your garage is behind a router?

    ReplyDelete
  4. MrQuincle - I have the USB Wi-Fi dongle's MAC address set to a reserved IP address on my network. I'm using simple port forwarding on the router from there.

    ReplyDelete
  5. I done see any particular garage hardware. does this work with any door opener?

    ReplyDelete
  6. Thomas,

    From my understanding, most any garage opener that takes two wires from a wall trigger will work. You just need some way to actuate it! Keep in mind you should not bypass any of the safety features of the opener, they're installed for a reason! :)

    ReplyDelete
  7. can it be use to control auto gate?

    ReplyDelete
  8. Can this method we use to control auto gate? tq

    ReplyDelete
  9. sQuare_bOx,

    This might be able to be used for a gate, it depends on the gate! If the gate works with a simple button / switch, it will more than likely work.

    ReplyDelete
  10. Another way to sense the status of the door (comes with bonus WAF) is to get one of the radio-link door indicators from Sears.
    A small unit sticks on the door and reports to a little box that sits in the house with a red&green LED on it.
    When the angle of the sensor changes from vertical to horizontal (door open), the LED shows red instead of green.
    You could tap into those LED circuits to tell the Pi the door status, and as a bonus the receiver is its own indoor status display.

    ReplyDelete
  11. Any chance you can provide better pictures of the wiring? Pi, relay and garage door unit.

    ReplyDelete
  12. P K,

    I'll try to get some additional pictures up this week.

    ReplyDelete
  13. Ryan, I really like you post and I am curious to build this myself. However I totally get lost in which pins to use. Can you post or email in detail which pins you used ( GPIOs and on the relais?) I really dont want to fry my pi connecting it wrong.

    I got the webserver up and running and got it accessible from the outside, just I am really bad in electro engineering.

    ReplyDelete
  14. Hello,i like your post and your structure of android powered.thanks for sharing such a fantastic post.Android News

    ReplyDelete
  15. this is so awesome! my girlfriend will never go to sleep with the garage open again!

    any chance we could convince you to include a more detailed tutorial or at least some more wiring pictures (or diagrams!!!)

    ReplyDelete
  16. I made an update to the post which describes the wiring in full. I hope it helps all of you!

    ReplyDelete
  17. This is exactly what I am looking for. Thanks a lot.

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. Can you tell me if I was to do this for two garage door openers would I just pick one of the other GPIO outputs like GPIO 22 and then just connect that to Label B (IN1) on the relay and then simply run wires from the 4th and 5th screw from the top to the other opener? Is there a way to set up the app to have two different sets of buttons like you've programmed for one? Lastly, can you set more than three options so that you can have an 'Open Door' just like your 'Close Door' or replace the toggle with this so you have absolute values rather than a toggle? Thanks for posting this!

    ReplyDelete
  20. Jeremy,

    Some slight modifications to the code would be necessary to support multiple doors. It definitely won't do it "out of the box". As far as adding an "Open Door" feature, the reason I didn't implement that is because it would only work in a single state (entirely closed). If you wanted to implement it, you would add a function in GarageDoorGPIO (the inverse logic of closeDoor() ) and add a hook into the service in the android app to call it. It would be quite easy! :)

    ReplyDelete
  21. very thanks for this post.i really want know more about this.if you understand My curiosity.Thank you for such nice tips

    Android News

    ReplyDelete
  22. Ryan, nice post. Thanks for sharing.

    ReplyDelete
  23. This comment has been removed by the author.

    ReplyDelete
  24. Hi Ryan or anyobdy...Could you please provide what type of optocoupler? I looked at the "2-ch relay module.pdf" but could not figure it out. A picture would be very helpful. Thanks

    ReplyDelete
  25. Is there a way to read the status of the magnetic switch using PHP only?

    ReplyDelete
  26. This comment has been removed by the author.

    ReplyDelete
  27. Can you describe in better detail what you had to set up on the RPI beforehand?

    I'm trying to get mine configured with Tomcat and SSL but it's not going well.

    I've installed apache2, php5, mysql, tomcat, and open-jdk-1.7_40.

    Apache web server works.
    Tomcat even works when I go to :8080, but SSL just always says ssl connection refused.

    ReplyDelete
  28. These directions are about as useless as they come. So frustrating given all of the lack of information.

    ReplyDelete
  29. Eric:
    I'll try to get a tutorial up for configuring Tomcat with SSL with the Pi.

    Dominic:

    The status of the magnetic switch is just reading the value of a pin. https://github.com/ronanguilloux/php-gpio looks like something you'd be interested in.

    John: As stated in my blog "I will be giving an overview of the project, but it is by no means a step-by-step tutorial". Aside from that, what in particular was especially useless?

    ReplyDelete
  30. Hey Ryan,

    I'm stuck at getting the servlet to run correctly. It is unable to find the auth.GoogleRealm class and am stuck really bad. Any ideas? My other error is that android gives a hostname not verified error.

    ReplyDelete
  31. Ryan,

    I am trying to build the Android Project, and I seem to be having difficulties with the "import com.blogspot.ryanfx.R" It seems that this is not checked in to the git repo. I have tried to reference android.R, but that doesnt seem to build either. Is there something I am doing wrong. I see lots of people have gotten this to work, so Obviously I must be missing something.

    Thank you!

    ReplyDelete
  32. the lack of instructions for getting the server / android app up and running are so frustrating. i'm not a programmer but a hobbyist, maybe this is over my head.

    oh, and the part where your provided link led me to buy *capacitors* instead of the needed *resistors*. So I just wasted $25... :-/

    You can make it right by making this article a little more complete. Everyone would love you...

    ReplyDelete
  33. John,

    I'll work on getting together a new post which will be a detailed tutorial on how to get the server going with SSL. Thanks for the feedback with the capacitors, the link is now fixed.

    ReplyDelete
  34. John,

    He stated before that this is not a guide on how to do it. It is a demonstration of what he did on his own. A complete how-to guide is much harder to write and it took me a couple full days to get it working. With some googling and searching it is doable. Blindly following his instructions (its downright insulting to blame the capacitor switch-up on him, look at what you are going to buy before handing out payment info).

    On the other hand, where are you stuck. I just got everything finally figured out and got over quite a few errors and such. I would be glad to give you a hand setting it up.

    ADJ

    ReplyDelete
  35. Unknown -

    I'm close (I think). I have tomcat working with SSL.

    I'm stuck with getting Android to trust the self-signed certificate. I'm not entirely sure what it takes to get bouncy castle installed on the rpi, and the portion in http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

    I just can't get it to "accept" the certificate, I guess.

    Also, when I generate/import the WAR file and then go to https://my.ip.addr.ess:8443/GarageWebService I get an HTTP Status 404 (The Requested resource is not available).

    ReplyDelete
  36. I got that error too, what version of android are you using? Also does the password you have in the SSLSocketFactory match the one from creating the keystore? If you copy paste the commands from crazybob then the password is ez24get

    ReplyDelete
  37. Also do you have tomcat manager installed? (sudo apt-get install tomcat-manager I think) I used that to deploy it and it took a couple code changes to work.

    ReplyDelete
  38. Where did you install the resistors?

    ReplyDelete
  39. The resistor goes between the switch and the 3.3v (PIN 1) GPIO pin.

    ReplyDelete
  40. I was finally able to get this to work. I would agree with some of the others that the instructions above aren't very good and in some instances, just has critical holes of information missing. Understandably this was just a guide, and thanks to Ryan for doing all the work. I have a few things below that I found that could help anyone else out trying to do this project.

    The few things I encountered off the top of my head:
    *JAVA 1.7 is required.
    *Tomcat has to run as root per the PI4J library. (that kind's sucks but it's a PI4J thing.)
    *The wiring instruction for the relay doesn't work. (u can google that quick)
    *context.xml should be full class path. com.blogspot.ryanfx.auth.GoogleRealm
    *And some JAR files i had to put in the tomcat share directory after the tomcat logs were showing they couldn't be found. It didn't seem like they were packaged right. (could be my fault)

    ReplyDelete
  41. As an update for everyone, I wiped out the pi and my build enviornment and rebuilt it / got it working from scratch - I will be posting all of the steps needed within the next day or two!

    ReplyDelete
  42. The configuration section has been updated with a step by step instruction on how to get it going. Please update your local copies from the repositories!

    ReplyDelete
  43. Awesome work buddy!! I think I'm gonna try out that amazing app to open up my garage door from remote areas. The effort will be definitely less and I truly admire that video tutorial. That was great. Thanks.
    number of android apps

    ReplyDelete
  44. This comment has been removed by the author.

    ReplyDelete
  45. 13. Copy mystore.bks to the machine which has eclipse
    From where? i cant find this file :o)

    ReplyDelete
  46. Steinar you get this file from running the keytool command

    ReplyDelete
  47. When I try to export the android application, it asks me for a keystore selection (existing or create new). I click "existing" and then browse the the mystore.bks file in the /res/raw/ folder, then put in the password I entered when I created the keystore.

    Now, when I click "Next" here, Eclipse tells me that it's an "Invalid keystore format". I've tried regenerating the .bks file twice and it doesnt work. It asks me for a key Alias (dropdown with no options to select) and password, OR to create a new key.

    What should I do here? Where did I go wrong?

    P.S. Thanks for the addition of the configuration section. VERY helpful!

    ReplyDelete
  48. I tried to just go ahead and create a new keystore for the android app and i was able to install the application onto my phone. I port-forwarded 8443 to my raspberry pi, and now I get

    "Error Occured - Status 401" and "Authentication Failure" when I try to toggle the garage door. Any ides where the authentication problem would be for this error code?

    ReplyDelete
  49. John,

    Double check that the web app is running as root. Also check that the text file containing your gmail account is readable by root and that is in the correct location!

    ReplyDelete
  50. Tomcat is running as root - so I assume the GarageDoor service is running as root as well (cant figure out how to double-check this, as it's not available from the GUI).

    Also I double checked the /root/garage_users file, the only line in it is my google account email/username and it is read-writeable by Root.

    Any other suggestions I can try?

    ReplyDelete
  51. so, as anybody successfully got this working, aside from the author?

    ReplyDelete
  52. This comment has been removed by the author.

    ReplyDelete
  53. i am stuck at https://localhost:8443

    ReplyDelete
  54. This comment has been removed by the author.

    ReplyDelete
  55. John, what I'd recommend is to setup remote debugging on Tomcat and put in some break points in eclipse. Step through the code until the authentication exception occurs. Google the terms remote tomcat debugging eclipse.

    Open up /etc/default/tomcat and there should be a line in there to uncomment to allow remote debugging. Attach to it with eclipse and do some exploring!

    http://wiki.apache.org/tomcat/FAQ/Developing#Q2

    ReplyDelete
  56. Ryan. Thanks for your patience and continued help while I sit here frustrated bc i'm a n00b.

    Anyway, I'm an idiot.

    I was using my google PW instead of server password that I hardcoded in GoogleRealm.

    Once I modified that in the app to match, everything worked. Well, I haven't hooked it up to my garage door yet, but the APP is working and interacting with the RPI remoteley.

    THANK YOU!

    ReplyDelete
  57. Thanks for this Tutorial . This is what I am looking for. I will start work on this immediately. Thanks once again.

    ReplyDelete
  58. This comment has been removed by the author.

    ReplyDelete
  59. This comment has been removed by the author.

    ReplyDelete
  60. This comment has been removed by the author.

    ReplyDelete
  61. This comment has been removed by the author.

    ReplyDelete
  62. This comment has been removed by the author.

    ReplyDelete
  63. This comment has been removed by the author.

    ReplyDelete
  64. Love this project, but I can't get it to work. Too much missing info for n00b.I run into so many errors and learned a lot.I understand that it takes a lot of time and effort to write step by step instructions.

    ReplyDelete
  65. How about we do this with https://www.spark.io would be easy as they already have cloud services and app.

    ReplyDelete
  66. This comment has been removed by the author.

    ReplyDelete
  67. Ryan - One other thing I'm stuck with is when I go to Export the app in Eclipse I'm using the existings keystore mykeystore.bks but it won't let me. The error I'm getting is invalid keystore. Do you have any idea why? Thanks.

    ReplyDelete
  68. tuan it looks like it could be a number of things, but some quick googling brings up this thread: http://stackoverflow.com/questions/6035970/invalid-keystore-problem

    ReplyDelete
  69. This comment has been removed by the author.

    ReplyDelete
  70. This comment has been removed by the author.

    ReplyDelete
  71. This comment has been removed by the author.

    ReplyDelete
  72. Great Project. Thanks for posting this. The directions were easy to follow and everything is working great. Just one question. I'm having a 1DTenT moment. How do I access this via http/https for non-android apps?

    Thanks.

    ReplyDelete
  73. Rob O'Reilly - Did you have any problems with keystore invalid format when you export the Android app? Thanks.

    ReplyDelete
  74. Power went out last night for me.

    Upon receiving power again, the garage door opened unexpectedly. Is there any way to prevent this from happening when power is restored? This could be detrimental if it happened while I wasn't home.

    ReplyDelete
  75. Fantastic article, Thanks for posting! I'm actually using apache and a custom web app, but used your guidance in selecting and hooking up the hardware. The only change I had to make was that I had to hook up a 5v pin to the VCC pin on the relay board (as opposed to the 3.3v pin you used) in order for the garage door wires to be connected. Thanks again, I could not have got it working without this post!

    ReplyDelete
  76. Ryan...Thanks for the article. I got across an exception saying "03-01 03:58:32.014: E/AndroidRuntime(1078): Caused by: java.io.IOException: KeyStore integrity check failed." Any idea what would be going with my keystore?

    ReplyDelete
  77. The earlier notified problem has gone with correct password (password used at the time of ssl creation). Now the new issue is with host name

    03-01 04:29:18.273: E/com.blogspot.ryanfx.service.GarageStateService(1053): java.io.IOException: Hostname '192.168.1.86' was not verified
    . Please advice.

    ReplyDelete
  78. Finally... the issue is with certificates.. I have signed up at dnsdynamic.org and used the hostname everywhere I had to enter needed and recreated certificates. That fixed the issue. No where it is mentioned..Ofcourse I am not an expert on these, Firewall port forwarding for raspberry device to be setup through router admin console. This will let the user to access raspberry device from outside through public ip.

    I think I am half way thru... I am thru between my cellphone and servlet application.

    ReplyDelete
  79. This comment has been removed by the author.

    ReplyDelete
  80. Ryan, thank you for writing this up!

    I have been able to get to the point where I have the app installed on my phone and I get:

    Error Occurred - Status: -1 javas.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x5ce291a0:
    Failure in SSL library, usually a protocol error
    error: 140770FC:SSL
    routines:SSL23_GET_SERVER_HELLO:unknown protocaol (external/openssl/ssl/s23_clnt.c:776 0x5ace3b86:0x00000000)

    Any ideas?

    ReplyDelete
  81. Ryan thanks again for putting this together! I feel like I am so close to figuring this out. My hang up is I am trying to set up the port forwarding on my router and am not sure what port I need to be forwarding. Do I need to be forwarding myRasPiIP:8443 or is the web service on another port? Any help on this would be greatly appreciated!

    ReplyDelete
  82. I also have a question when your creating the cert if your doing port forwarding with your router. For the question "What is your first and last name?" do I put myIpAddress:portToRasPi or does it need something like http:// added?

    ReplyDelete
  83. Thank you for this Ryan! I rent and I can't replace our garage door opener with a newer one with these features already built in. I love the options with Raspberry Pi. Thank you for a pretty complete step by step guide for this.

    I do have one question. Can we simply modify the users list and add a second gmail to use if my wife and I both want to use this from our phones?

    ReplyDelete
  84. This comment has been removed by the author.

    ReplyDelete
  85. I have everything hooked up and the app is giving me a message saying"Error Occured - Status -1 failed to connect to /ipaddress(port8443)after 3000ms."

    I have port forwarding set up. Curious if it is one of the firewall setting. Can anyone confirm?

    ReplyDelete
  86. This comment has been removed by the author.

    ReplyDelete
  87. Hi Ryan


    How do I "Transfer GoogleAuth.war to the Rpi"?

    Thanks

    ReplyDelete
  88. If you have a windows computer you can use winscp to connect to the pi and transfer the file to the appropriate directory.

    ReplyDelete
  89. Thank you for your response. But the thing is.. I don't know which directory to transfer that file to

    Thanks

    ReplyDelete
  90. I transfered it into a downloads folder I created and then moved it once back in the pi using commands.

    ReplyDelete
  91. This comment has been removed by the author.

    ReplyDelete
  92. I have two questions

    1. Could someone tell me where or how I can upload the GarageWebService to TOMCAT web server? I believe it's /var/bin/tomcat7/webapps/ROOT. But it tells me I have no right to put the GarageWebService in there.

    2. I'm stuck on this step: "Create a new folder called raw inside of the res folder." Where is this at?

    Thank you

    ReplyDelete
  93. 1. If I understand correctly, you have finished with it in Eclipse and are moving it to the Pi correct? Or is this to actually start it in tomcat? You should be able to load tomcat by going to the browser from a different pc on the network and typing in the ip of the pi. THen click on manager link and then you have an option to upload it. You should have already placed it on the Pi in a directory wasy to reach. I made a downloads directory under /home/user to make it simple and that held all my transferred files.
    2. In eclipse simply right click on the res folder and make new folder. Name it raw and put the file referenced into it.The res folder is in the trees though I can't remember which one exactly off the top of my head.

    Hope that helps. If not please feel free to respond and I will help how I can.

    ReplyDelete
  94. HI Lenin

    Thank you for getting back with me. Yes, I've deployed the .war file using the web interface, but when I tried to access it via https://MYIP:8443/GarageWebService, I received a message:

    "HTTP Status 404 - /GarageWebService


    type Status report

    message /GarageWebService

    description The requested resource (/GarageWebService) is not available.


    Apache Tomcat/7.0.28"

    And secondly, I am not sure which folder is the "RES" folder

    ReplyDelete
  95. That's the issue. You should be trying https://myip:8443

    then clicking the manager link on that page. It will take you to apache tomcat manager and you then upload the file and start.

    As for the res folder it is in the android source code file when you start the existing android project to make the actual app in eclipse. dig into the expanded items and you will see it.

    ReplyDelete
  96. This comment has been removed by the author.

    ReplyDelete
  97. I don't know if anyone is still keeping up on this post, but I am wondering if an update to eclipse didnt kill the authentication on this. When I build the APK, it tells me that the keystore type is wrong. Is it not excepting. BKS anymore?

    ReplyDelete
  98. This comment has been removed by the author.

    ReplyDelete
  99. Chris,

    I have/had the same issue with creating the APK. It does accept a JKS file... However I'm getting authentication errors in the Android app.

    ReplyDelete
  100. Chris, use garagessl when making the APK. I also had to put GoogleAuth.jar in /usr/share/tomcat7/lib to get this working.

    ReplyDelete
  101. you don't have a working remote then you'll need to program the garage door remotes into the power head and then transfer the code to the garage door remotes
    entry using the jumper.

    ReplyDelete
  102. I have everything hooked up and the app is giving me a message saying"Error Occured - Status -1 failed to connect to /ipaddress(port8443)after 3000ms." when i try to connect from android app in cell phone.. any idea?

    I did router ippassthrough and when i hit my url its working , i can go to manager app.

    ReplyDelete
  103. sudo mv GoogleAuth.jar /usr/share/java/

    sudo ln -s ../../java/GarageAuth.jar .

    Ryan,

    You generated a GoogleAuth.jar but mentioned to create a softlink with GarageAuth.jar ..is this correct step?

    ReplyDelete
  104. will it works for only one door? or if i have multiple garage doors will it open and close all at once when i click on open button?

    any advise?

    ReplyDelete
  105. This comment has been removed by the author.

    ReplyDelete
  106. Everything works fine except when I get to step #20:

    I suspect the keystore.bks generation ins step #12 to be the issue.

    I saw some feedback below that suggests using "garagessl" file created in step #1 instead.

    Just to confirm, we should be placing the "garagessl" file in the "raw" directory when creating the application?

    Comment from above:
    "Chris, use garagessl when making the APK. I also had to put GoogleAuth.jar in /usr/share/tomcat7/lib to get this working."

    ReplyDelete
  107. This comment has been removed by the author.

    ReplyDelete
  108. Great idea

    Wish I could get it to work. I can connect to the Tomcat server on the Pi from outside my network using my .ddns and port 8443 from my Nexus5. But the app throws up:
    isConnected failed: EHOSTUNREACH (No route to host)
    or
    isConnected failed: ECONNREFUSED (connection refused)
    or
    Status 404.

    Has anyone got this working recently?

    If anyone can point me to a possible solution I'd be grateful

    Thanks

    Mal

    ReplyDelete
  109. Hi Mal, have you set the server address in the app itself from the config page ?

    P.S. Thanks Ryan great app.
    I have changed mine to use piface instead of the external relay board and have recently added notifications, now I get notified if the garage opens or closes.

    ReplyDelete
  110. Hey Stephen

    Thanks for the reply, and yep host address is set in app. I've scrapped it and rebuilt it from scratch a few times now on 2 different eclipse installs there is clearly something I'm missing but can't find it for the life of me.

    I have the app pointed to my NoIP ddns and my fritzbox forwarding my selected port, the NoIP DUC is installed and working as I can access the Pi with other apps no probs. I'm thinking it may be something Iscrewed up with the auth key setup but I'm not clued up enough to troubleshoot it.

    ReplyDelete
  111. So I have a bit of an issue I need to get around. My garage uses 398LM Control Panel to open and close the door. Everytime my PI triggers the door to open or close, my Control Panel shorts out. This usually requires me to physically disconnect and reconnect the control panel to the system. I thought maybe diodes to control the direction of the signal might help, but that lead me no where. Any ideas?

    ReplyDelete
  112. Chris If I were you try 398lm control panel replaced by 888lm. Automatic Gate Openers

    ReplyDelete
  113. Thanks for your hepful guide.aodretail is a site for garage doors and operator parts. It's the one stop solution for your needs with best garage doors and operator tools. I made my shopping with them and I must admit, their product quality is quite good.

    ReplyDelete
  114. Presently there are special garage door oils that you can use to resolve the problem but you can always get in touch with the experts if you continue to be concerned and worry there could exist an additional problem. garage door opener repair

    ReplyDelete
  115. Next, check the springs of the doorway openers and make sure that it is hooked into the holes or notches on each side of the doorway. When you face any difficulty while you are carrying out the brooklyn garage door repair try adjusting the tension in the garage doors by removing the spring hook to the next hole or notch. stanley garage door repair

    ReplyDelete
  116. This is such a great resource that you are providing and you give it away for free. I love seeing blog that understand the value of providing a quality resource for free. Garage repairs

    ReplyDelete
  117. Thomas,

    From my understanding, most any garage opener that takes 2 wires from a wall trigger can work. you simply would like how to actuate it! confine mind you ought to not bypass any of the security options of the opener, they are put in for a reason! :)

    Garage door repairs north shore
    Garage doors northern beaches

    ReplyDelete
  118. Thanks for sharing valuable post !
    informative and very useful knowledgeable.
    los angeles garage door repair

    ReplyDelete
  119. Ktronics is the Best Wireless Water Level Controller manufacturer in Chennai. For Any Products Related Query Feel Free to Contact us : 9043876528:Website.

    ReplyDelete