Context Sensing for Mac OS X
Pennyworth + AppleScript
AppleScript is the primary technology used to communicate between Pennyworth and other applications. Applications can use AppleScript to log custom sensor readings (such as a game providing play/pause status) that Pennyworth can include in its context predictions. Likewise, Pennyworth can "command" other applications using AppleScript when the user's context changes.
Both techniques are described below.
Logging custom sensor readings
If you are developing a custom application and you would like to expose contextually-relevant information to Pennyworth, you can do so by using Pennyworth's built-in AppleScript support. The general form of these scripts is
if application "Pennyworth" is running tell application "Pennyworth" to log OBSERVATION with duration DURATION from observer OBSERVER end if
If we were writing a context-aware e-mail application and wished to where whether the user was reading or writing a message, we would replace
To distinguish our mail client's reading from other observations, we would replace
Thus, the code our e-mail client would call would look like this
if application "Pennyworth" is running tell application "Pennyworth" to log "Writing" with duration 600 from observer "My E-Mail Client: Status" end if
To erase an active reading (one whose duration has not elapsed), we would log another observation with a short duration of 0. This is a useful technique for clearing readings on application termination.
Note: This technique can be used to augment Pennyworth's sensors in two ways. When included with an application, such a script may be called using
folder. Pennyworth will call these scripts automatically every 30 seconds. I use this technique to write sensors for applications such as Mail.app, Adium, Skype, and iChat. These scripts (and others) may be downloaded from the AppleScripts repository.
Controlling other applications with Pennyworth
If you're a developer wishing to create an application that reacts to changes in your users' context, the best way to accomplish this is to provide a full-featured AppleScript dictionary and implementation.
Pennyworth uses AppleScripts to control other applications. For example, if you want to listen to a particular playlist when you are reading, you can define an AppleScript that is called on context changes. These scripts follow the general form
on prediction(type, prediction) if (type is equal to "Foo") then tell application "Bar" -- do something end tell end if end prediction
Pennyworth passes two arguments to a function called
As an example, here is a script that updates your Adium status with your current activity:
on prediction(type, prediction) if application "Adium" is running if (type is equal to "Activity") then tell application "Adium" set the status message of every account to prediction end tell end if end if end prediction
The check to see if the application is running is important because Pennyworth will launch Adium if it is not running and this script is called. Also note that there is a small delay (5 seconds) between when Pennyworth generates a new context prediction and when that prediction is sent to the AppleScripts. This is used to throttle the number of AppleScript invocations when the learner is generating many different predictions in a short period of time.