3 Comments

Summary:

“Wouldn’t it be cool if you could control your Christmas lights from your iPhone?” That simple question, posed in passing eleven days ago by a good friend, set off a flurry of activity which has become Griswold.app (for the iPhone/iPod touch) and Griswold Server (for OS […]

“Wouldn’t it be cool if you could control your Christmas lights from your iPhone?” That simple question, posed in passing eleven days ago by a good friend, set off a flurry of activity which has become Griswold.app (for the iPhone/iPod touch) and Griswold Server (for OS X Leopard, Windows and Linux/BSD). Both are being released here with full source to each and you may just be able to download it from the App Store by the end of the week as well.

If you are one to deck the halls…and the family room…and the kitchen…and the roof then you know how difficult it can be controlling all those displays. Timers are somewhat effective, but are always out of sync with each other. Simple RF remotes provide better control but must be in range or have line-of-sight to work. It really would be cool to be able to control these creations from an iPhone!

It’s A Long Way Down Holiday Road

To view the Xcode project and build the iPhone app you will need a copy of the iPhone SDK from Apple. That Xcode install will also meet the needs of the back-end server. You will need to download both the Griswold iPhone app source (ZIP) and the Griswold Server app source (ZIP).

In terms of hardware, you will need an X10 FireCracker starter kit (I recommend purchasing from X10-Express as they have better prices and no pop-ups). NOTE: You may need more X10 outlets depending on the scale of your display. Since your Mac undoubtedly does not have a serial port, you will also need a USB<->Serial adapter (SerialIO has a decent one). The FireCracker module that attaches to your Mac sends wireless commands (i.e. “on”, “off”) to the receiver which relays them to the X10 “network” of modules. This is all maintained by the server component:

The iPhone interface needs an IP address to talk to and you can use either the local or remote one, but for the “remote” one to work, you will need to configure port-forwarding on your Internet router (forward TCP port 8786 to the internal address).

Each X10 “switch” is addressed by a house code and unit code. Griswold Server lets you choose which house code your display is on and can either control a single unit code or all unit codes for a house code. You must choose the serial interface the FireCracker is connected to and you have the option of defaulting your display to “on” when the server starts up. “Seekrit” also needs to match what you enter on the iPhone.

You really do not need the iPhone controller as you can turn the system on and off right from the server console window. But that’s not nearly as cool.

The server is written using the Python-Cocoa bridge and may be a good starting point for folks who are looking into doing development on the Mac. The application has full Growl support and uses the Sparkle framework for automatic updates (in the event you want to just use the server without compiling from source, it, too, is available). You can watch for errors in ~/Library/Logs/Griswold Server and take a look at the configuration file in ~/Library/Preferences/Griswold Server/Griswold Server.plist.

For Your iPhone

As you can see below, the iPhone interface is pretty straightforward. The initial screen shows you the current status (display is on or off) and presents you with a simple, singular control to change that stats:

As noted earlier, the configuration screen asks you for an IP address and secret code (akin to “pairing”) and gives you the ability to test the connection or force the system to an on or off state.

Since the application’s main function is to pass commands back to the server and retrieve current display status, the majority of the the work is done via a very handy utility method:

       NSString *myResponse = [ NSString stringWithContentsOfURL:url
                                  encoding:NSUTF8StringEncoding error:&error ] ;

All you have to do is create a URL and NSString takes care of setting up the connection, issuing the request, closing down the connection and converting the result to an immediately usable Cocoa string.

Prior to calling this method, it is important to know whether one should bother to since the device may not have connectivity.

   if ([ RootViewController isServerReachable:hostnameOrIPValue ] &&
       [ RootViewController canConnect:hostnameOrIPValue
                            onPort:8786 withTimeout:5.0]) {

A quick test (the above code) accomplishes this and relies on two equally simple methods — isServerReachable: & canConnect:. The first takes advantage of the iPhone SDK “reachability” API, but that just tells you whether there is a network path to the host. The second one actually makes a TCP connection on a specified port with a timeout (to avoid hanging the UI) and lets the caller know whether full connectivity is possible.

+ (BOOL)canConnect:(NSString *)ipAddress onPort:(int)port withTimeout:(double)seconds {

    @try {

        CFSocketRef socket ;

       // We justneed a TCP socket. Nothing fancy.

        socket = CFSocketCreate(kCFAllocatorDefault,
                                PF_INET,SOCK_STREAM,IPPROTO_TCP,
                                0,NULL,NULL);
        struct sockaddr_in sin;

        memset(&sin, 0, sizeof(sin));
        sin.sin_len = sizeof(sin);
        sin.sin_family = AF_INET;
        sin.sin_port = htons(port); // port we want to connect on
        sin.sin_addr.s_addr = inet_addr([ ipAddress UTF8String ] );

        CFDataRef address = CFDataCreate(NULL,(unsigned char*)&sin,sizeof(sin));

        CFTimeInterval timeout = seconds ; // how long to wait before returning

        CFSocketError e = CFSocketConnectToAddress(socket,address,timeout);
        CFSocketInvalidate(socket) ;

        CFRelease(address);
        CFRelease(socket);

        return(e == 0) ;

    } @catch (id SocketException) {

       return(NO) ;

    } // if //

}

Overall, it is a pretty basic iPhone application, but it does have all the fundamental elements of a utility app including integration with the iPhone Settings (NSUserDefaults) interface.

Keeping In Control

If you just want to play and do not want to develop, then grab the standalone server app (again, Leopard-only) and e-mail me (bob at rudis dot net) your iPhone UDID (Ad Hoc Helper from the app store can help with this). I have some free ad hoc distribution slots that I’d be willing to part with.

I plan on updating Griswold Server to add more granular control over X10 modules (and update the iPhone app UI accordingly), include scheduled on/off execution and may add the option to have it rest in the menu bar vs the dock (all of which is feedback from my awesome beta testers).

If you have a Windows or Linux box, or just want to keep up with the development of Griswold, head over to griswoldapp.com or contact me for more information.

  1. Fred Hagemeister Saturday, February 7, 2009

    Great job! Not having done iPhone SDK before, some brief info about acquiring the SDK, installing it, loading the Griswold project, and compiling it would help, but it worked okay. Would there be a problem with Apple, if you compiled Griswold.app and distributed that file?

    Share
  2. Hi,

    Very nicely done. This is exactly what I have been looking for, for a very long time. Thanks. The link to the server code (http://gigapple.files.wordpress.com/2008/12/griswoldserver-src.zip) seem to be broken.

    Best Regards,

    Frank.

    Share
  3. [...] iPhone amp OS X DIY Take Control Of Your Holiday Displays With Griswold Posted by root 21 hours ago (http://theappleblog.com) Dec 16 2008 if you are one to deck the halls and the family room and the kitchen and the roof then you know how difficult it can the link to the server code http gigapple files wordpress com 2008 if you 39 d like an avatar to appear next to your comment i Discuss  |  Bury |  News | iphone amp os x diy take control of your holiday displays with griswold [...]

    Share

Comments have been disabled for this post