think logo

Site Info

Categories

Archives

Meta

Geo

Museum

Recent Posts

Recent Comments

 

February 2012
S M T W T F S
« May    
 1234
567891011
12131415161718
19202122232425
26272829  

Remotely boot your iPad and launch an app

May 25, 2011

I’m one step further along on the quest for the Holy Grail of kiosk displays. We use a lot of iPads here at the museum, most of them are either in Lab Shield brackets or built into cabinets. The whole idea behind building a kiosk is to make it hard for people to break into your device, so naturally the power and home buttons are behind lock and key.

The trouble is, there are a few quirks in the iPads. One is that after running for a few days, the display seems to lose its sensitivity to touch. The only way so far to deal with that seems to be to open the bracket, hit the power button to make it sleep, then hit it again to make it wake up. Then launch the app again and lock the whole thing back up. Not something the visitor services people want to do a lot. Nor I.

Sometimes visitors also break out of the kiosk app (we’re using iCab Mobile, an absolutely fantastic app, by the way). I have no idea how, but sometimes the iPad will be doing something completely different. One of ours now has a spiffy new home screen background thanks to someone who got in.

I’m very hopeful that my newly found method of remote booting/app launching will help at least take some of the pain out of the reset process.  Here’s how:

  1. Jailbreak the iPad (only works on iPad 1′s for now)
  2. Install OpenSSH (I installed the whole BigBoss Recommended Tools suite)
  3. Install Activator
  4. Determine the IP address of the iPad
  5. ssh in as root, change the password right away!
  6. Set up Activator to launch whatever app (e.g. iCabMobile) you want to have start up at boot time. Hook the app to the “Anywhere -> Power -> Connected” event.
  7. If you’re still ssh’ed in from step 5, type ‘reboot<return>

Voilá. Your iPad will reboot, and if you’re crossing your fingers just right, the app will launch after it boots. It seems to do this pretty reliably unless you do it too many times in too short a time.

I’ve set up ssh keys for the iPad so that I can run a command like this from my desktop machine:

ssh -i .ssh/id_rsa_ipadkiosk root@192.168.1.52 reboot

Next up on my list is to build a web app that lets us reboot any iPad. Then we can carry around an iPad running the web app, and reboot troublesome exhibits with the swipe of a finger.

Update: I should note that for this to work, the iPad has to be plugged in to a power source. During the boot sequence the hardware must sense the power source and generate the same event that gets generated if you plug it in after it’s booted.

Mac OS X user idle time in Python

March 3, 2011

I’m still on the quest for the perfect free kiosk app for Mac OS X. I’ve used Plainview to good effect in several exhibits. I’ve used Opera in one, and I’m using Firefox with R-Kiosk in another. Which program to use depends a lot on the nature of the web page(s) to be displayed in the kiosk and the way the user expects to interact with the kiosk.

For the Firefox kiosk, I needed a sure-fire way to reload the home page after a certain amount of idle time. The trouble is that Firefox doesn’t lend itself to be controlled via AppleScript. A lot of poking around led me to learn about AppleScript System Events being able to simulate a keypress, that Option-Home will make Firefox load the home page, and that there’s a really handy little application called Full Key Codes that tells you what the key code is for any key you press on a Mac.

That let me put together this handy little Python script that watches how long it’s been since a user has done something. First it waits until there’s been any user activity at all, then it waits until there’s been no activity for 90 seconds. Then it uses osascript to run a little bit of AppleScript that sends Option-Home (key code 115) to Firefox.

I suspect there’s a way to eliminate the osascript by using the Python objc module, but this is good enough for me…

#!/usr/bin/env python
 
#========================================================================
#
# idle.py - makes Firefox load home page after user inactivity
#
#       Set the value of 'timeout' to the number of seconds of idle
#       time you want to allow before reloading the home page
#
#       Comment out the calls to status() if you don't want to see any
#       messages
#
#========================================================================
 
from subprocess import Popen
from time import sleep
from Quartz.CoreGraphics import *
 
# From /System/Library/Frameworks/IOKit.framework/Versions/A/Headers/hidsystem/IOLLEvent.h
NX_ALLEVENTS = int(4294967295)  # 32-bits, all on.
 
# Set this value to the number of seconds of idle time before
# resetting Firefox
timeout = 90.0
 
def status(state, last, idle):
    """Print out some info about where we are """
    print "%10s %.1f %.1f" % (state, last, idle)
 
def getIdleTime():
    """Get number of seconds since last user input"""
    idle = CGEventSourceSecondsSinceLastEventType(1, NX_ALLEVENTS)
    return idle
 
def doReset():
    """Use osascript to tell Firefox to reload the home page"""
    reset = """/usr/bin/osascript \
        -e 'tell application "Firefox"' \
        -e ' activate' \
        -e 'end tell' \
        -e 'tell application "System Events"' \
        -e ' key code 115 using option down' \
        -e 'end tell' """
    Popen(reset, shell=True)
    sleep(1)                    # Prevent osascript keypress from triggering below
 
last = 0.0
idle = 0.0
 
while True:
 
    # These two lines can also be at the very end if you don't want to
    # load the home page once when the program starts
    status('--- RESET', last, idle)
    doReset()
 
    idle = getIdleTime()
    last = idle
 
    # Wait for user activity
    while idle >= last:
        status('wait', last, idle)
        sleep(1)
        idle = getIdleTime()
 
    # Wait for idle to become bigger than timeout
    while idle < timeout:
        status('triggered', last, idle)
        sleep(1)
        idle = getIdleTime()

Building a kiosk

June 24, 2008

At the museum, we’re setting up a kiosk to let people browse our online collections database. We’re very much in the mode of trying things out using a simple setup and then when we see how that works, we can tweak it as needed.

The basic requirements were to let visitors browse a single website (http://webmuseum.mit.edu) but not to be able to follow any of the outgoing links. Additionally, the visitors should not be able to leave the web browser and start mucking about with the underlying computer.

Even though our old PowerMac G4‘s are dropping like flies with broken power supply units, we have two left in the “good enough to reuse” bin. So I set one up with Mac OS X 10.5. Using MacPorts, I installed Squid and set up the network to use that squid as a proxy. Squid lets you configure which URLs it will go out and get, and which ones it will return an error on. I set it up to only return pages in the webmuseum.mit.edu site, and whenever a link outside that site is requested, it returns the toplevel page at http://webmuseum.mit.edu.

So far so good. The next thing I needed was a browser that won’t let visitors do too much other than browse. Luckily last week I bumped into Plainview. Plainview is a webkit based browser with no chrome. It also happens to have a kiosk mode that requires a password to get out of.

Then I set up a user account with Parental Controls, and only allow it to run the Plainview app and nothing else. I have the Mac boot up with that user login coming up automatically, and Plainview starts as a login application. Presto, a nice web kiosk. If users break out of Plainview, they can’t do anything else but log out of the system. We’ll see how long that takes…

One minor hitch in the entire setup – I don’t know whether it’s possible to set up Plainview to go directly into kiosk mode. Right now you have to type ⌘-/ and enter an administrator password to start kiosk mode.