Using the Notification Trigger in Power Manager

Power Manager has the ability to trigger events on receiving a system wide notification, and to post system wide notifications as part of an event's actions. For developers, and for those integrating Power Manager into their workflow, these two abilities are a great way of loosely chaining tools together.

Power Manager has the ability to trigger events on receiving a system wide notification, and to post system wide notifications as part of an event’s actions. For developers, and for those integrating Power Manager into their workflow, these two abilities are a great way of loosely chaining tools together.

The system wide notifications used by Power Manager are a standard part of Mac OS X. Notifications can be posted and observed by any other process, including scripts, daemons, C/CoreFoundation based applications, and Objective-C/Cocoa based applications. We will look at the code required to post a notification shortly.

First, let’s create an event that will be triggered when a specific notification is observed.

Create with Professional, Deploy on Standard

The notification trigger and notification action are not exposed in the interface of the standard edition of Power Manager. To create and configure these items, you will need to use Power Manager Professional or an alternative interface to Power Manager such as AppleScript.

Every edition of Power Manager supports the notification trigger and action. You can create the event with Professional, or via AppleScript, and deploy the final schedule across your Macs running Power Manager.

Triggering an Event with a Notification

Create a new event with a single trigger. Set the trigger to be Notification.

A notification triggered event in Power Manager Professional

The notification trigger has one required field and two optional fields. The required field is called Notification and this is the name to observe and act upon.

We recommend using a reverse-domain-name style format for system wide notifications. This format helps stop naming collisions by ensuring uniqueness between processes from different developers. The format also helps to provide a suggestion as to the source and cause of the notification.

By default, notification triggers automatically observe system wide notifications. These kinds of notifications are also know as host wide or distributed notifications. The trigger’s optional Scope field controls this behaviour.

With your trigger set up, next add a suitable action to your event. In our case, we have asked the computer to show a warning. You might want to launch an application or start a back up script.

Save and deploy this event to your local Mac.

Issuing the Notification

With the event deployed we can move onto how to post system wide notifications.

The following two code snippets both post a system wide notification that will trigger our event.

The first code snippet is for an Objective-C based application requiring only the Foundation (Cocoa) library.

#import <CoreFoundation/CoreFoundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"uk.co.dssw.recipe.notification-example"
                                                                   object:nil
                                                                 userInfo:nil
                                                                  options:NSNotificationPostToAllSessions];

    [pool drain];
    return 0;
}

The notification needs to be posted through the distributed notification centre, and the option flag to post to all sessions must be set. Without these settings the notification will not reach Power Manager’s daemon process.

This is all that is needed to trigger the event programmatically from Cocoa.

The second code snippet is for a C based application and requires only the CoreFoundation library.

#include <CoreFoundation/CoreFoundation.h>

int main (int argc, const char * argv[]) {

    CFNotificationCenterRef distributedNotificationCenter = CFNotificationCenterGetDistributedCenter();
    CFNotificationCenterPostNotificationWithOptions(distributedNotificationCenter,
                                                    CFSTR("uk.co.dssw.recipe.notification-example"),
                                                    nil,
                                                    nil,
                                                    kCFNotificationPostToAllSessions);

    return 0;
}

As with the Objective-C example, the notification must be posted via the distributed notification centre and the post to all sessions flag must be set.

This is all that is needed to trigger the event programmatically from C.

Note the lack of any mention of Power Manager in the code snippets. The code does not require the Power Manager framework, or any non-standard libraries.

This is an important aspect of the notification trigger and action. The lack of coupling between the posting and observing processes allows for creative solutions to difficult problems, without requiring tightly intertwined infrastructure.