Tuesday, September 18, 2012

Coding for a broken phone

So I've been very slowly working on a project to create a network-based garage door sensor (and possibly opener) which will let me check whether the garage door is open (when I left for a trip and suddenly panic because I can't remember if I closed it), and will also alert me if it's after 10 and I accidentally left it open. (Eventually I'd like to add a controller, so I can open/close it from my phone, but that's a long way off).

The first step was finding an easy way to sense if the door was open, and report that to my home server so it could serve it up to me.  Luckily my office-mate handed me his old android phone with a busted screen. Nothing shows up on the screen, and it the touch sensors don't work. 

Theoretically, I can mount the phone near the top of the garage, and write a program for this phone that will monitor the proximity sensor to tell if the door is open or closed (if I position the phone so that the open garage door will sit right in front of the phone near the ceiling) then report that to the home server over wifi.

So the things I would need to figure out:

  1. Can I even get code running on this thing without ever touching the screen?
  2. Can I get the proximity sensor working?
  3. Can I get the phone onto my wifi without being able to use the wifi configuration UI?
  4. Can I figure out how to physically mount this thing on the ceiling of the garage so it will work?
  5. Can I do all that before getting bored with the project?

1 was easy -- plug in the phone, fire up adb, and go to town. The Android debugging tools work just fine. Luckily Tim had enabled USB debugging before breaking it, or I might have been completely out of luck.

#2 was easy as well. The API for handling the phone sensors is pretty straightforward and easy to work with.

#3 was the most painful. I spent a good while tonight trying to figure out if I could configure the wifi just using adb (the remote debug tool for android). Couldn't figure out how to do it. So then I found the API for doing it programmatically -- so I need to write a program to configure the wifi before doing the rest of the monitoring. The sample code was really simple. Unfortunately it kept not working. And not working. And not working. With no reason reported of why -- either the call to enable my wifi network just failed, or it succeeded, but never connected. *sigh*. Finally figured it out after a ton of mistakes (the most notable, if anyone is here looking for help, being that the SSID and password have to be quoted inside the string, like:  String SSID = "\"myssid\"";, and the Android manifest needs to specify some uses-permissions: CHANGE_WIFI_STATE, ACCESS_WIFI_STATE, and ACCESS_NETWORK_STATE) 

So I finally tonight got that working. Next step: write the code to tie all this together. Then try to figure out how to mount it on the ceiling. Someday I might actually finish this thing.

If anyone tries to do this as well, here's a snippet of code that worked for me:

In the manifest:
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
And the code itself:
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"mySsid\"";
conf.preSharedKey = "\"1234567890\""; 
conf.status = WifiConfiguration.Status.ENABLED; 
 
int res = wifi.addNetwork(conf);
wifi.disconnect();
wifi.enableNetwork(res, true);
wifi.reconnect();                
   
wifi.setWifiEnabled(true);

NES Anguna

Well, I had a little bit of time still, while Frankengraphics is finishing up her game Project Blue, to have a little downtime on Halcyon, s...