Controlling SandUhr with CORBA

Prev |  | Next

# 4. Controlling SandUhr with CORBA

SandUhr features a full-grown CORBA interface. This can be used to create new timer objects from scripts or programs or to query or modify existing timer objects. The interface even allows you to plug in custom alarm actions, for example to deliver an alarm message by email.

## 4.1. Introduction to CORBA

CORBA is a complex framework, designed to tie together pieces of a program, which may be written in different programming languages and may run on different computers in a network. The full list of buzz-words may be found at the official CORBA web site www.corba.org.

CORBA is object oriented. A CORBA server implements objects. A client sends requests to these object, to perform specific tasks. The SandUhr application implements two classes of objects:

- `SandUhr::Timer` objects. These correspond to the sand-glass shaped windows you see on your screen. They implement requests to set or query the items from the timers properties dialog.

- `SandUhr::TimerFactory` objects. Each instance of the SandUhr program implements one factory object. This loosely corresponds to the SandUhr control window from the timers' popup window. The main function of these factory objects is to create new timers.

The CORBA support of SandUhr is implemented with the help of ORBit, the standard CORBA ORB for use with the GNOME environment. You can find more information about ORBit at the ORBit homepage. The inter-ORB-communication is standardised, so in theory you can use any ORB implementation to access SandUhr. If you want to learn more about CORBA you should read the CORBA Applications In GNOME white-paper by Elliot Lee. It is published on the GNOME development site.

In all examples below I will use the Python bindings for ORBit. You can find these at orbit-python.sault.org. You will also need the GNOME OAF library. I use the python bindings which are included in the bonobo-python package at bonobo-python.lajnux.nu.

## 4.2. Simple scripting with CORBA

Using CORBA to create a new timer is easy. The only problem is, to get hands on a `SandUhr::TimerFactory` object. Once we have this object, we can ask it, to create a timer for us. This problem is solved by the GNOME object activation framework OAF. We can simple ask the OAF for a CORBA object, which implements the `SandUhr::TimerFactory` interface. This is demonstrated by Example 3.

Example 3. Creating timer objects with CORBA

The following Python script creates a timer which expires after 30 seconds. If you run this script, it should open a new timer window, and terminate immediately (without waiting for the timer to expire). If you are not using ORBit-Python you may need to call your ORB's IDL compiler to generate the SandUhr module.

Of course you can do the same thing not only in Python, but in any language which has bindings for CORBA and liboaf. The code will look similar.

    import CORBA, oaf, SandUhr

    oaf.init()
    factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
    factory.CreateTimer ("+30s", "timer expired")

Once you have mastered this example, it is really easy to further customise the timer. Example 4 shows, how to create a pink timer, which beeps five times instead of three. The full list of available requests is documented in SandUhr::Timer(3).

Example 4. Customising timer objects with CORBA

The following Python script creates a pink timer which beeps five times when the alarm time is reached.

    import CORBA, oaf, SandUhr

    oaf.init()
    factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
    timer = factory.CreateTimer ("+20s", "pink timer expired")

    timer.SandColor=SandUhr.Timer.Color(Red=212,Green=78,Blue=222)

    alarm = factory.CreateAlarmBeep (5)
    timer.Alarm = alarm

## 4.3. Advanced CORBA examples

A more involved usage of the CORBA interface is to plug new alarm actions into SandUhr. This allows you to run arbitrary code to deliver an alarm message. Example 5 below shows how you can deliver the alarm per email.

Here your application has to act as a CORBA server, which implements the the `SandUhr::AlarmAction` interface. The interface is documented in SandUhr::AlarmAction(3). Your server has to implement the `SandUhr::AlarmAction::NeedsPopup` attribute and the `SandUhr::AlarmAction::Attach`, `SandUhr::AlarmAction::Detach`, and `SandUhr::AlarmAction::Deliver` methods.

In object oriented programming languages usually the ORB implementation will provide a class named similar to `SandUhr__POA::AlarmAction`. For the Python bindings it is called `SandUhr__POA.AlarmAction`. To implement the alarm action you have to derive a subclass of this class and to overload `NeedsPopup`, `Attach`, `Detach`, and `Deliver`.

Because SandUhr must access the object implemented by your server, you have to keep your server running until the alarm is delivered. Usually this is achived by calling the `ORB::run` method of your ORB implementation.

Example 5. Delivering the alarm by email

The following Python script implements a SandUhr alarm action to deliver the alarm via email. You must adjust the variables `EMAIL` and `SENDMAIL` to fit your local setup. If you run this script it should open a timer window and start to sleep. After 60 seconds it should send an email and then quit.

    EMAIL = "Addressee <some@email.address>"
    SENDMAIL = "/usr/sbin/sendmail"

    import os
    import CORBA, oaf
    import SandUhr, SandUhr__POA

    orb = oaf.init()

    class SendMailAlarm(SandUhr__POA.AlarmAction):
        def __init__(self):
            self.NeedsPopup = CORBA.FALSE

        def Attach(self, timer):
            pass

        def Detach(self, timer):
            orb.shutdown(1)

        def Deliver(self, timespec, message):
            p = os.popen("%s -t" % SENDMAIL, "w")
            p.write("To: %s\n" % EMAIL)
            p.write("Subject: SandUhr: %s\n" % message)
            p.write("\n") # blank line separating headers from body
            p.write("A SandUhr timer has expired.\n")
            p.write("  alarm message: %s\n" % message)
            p.write("  alarm time: %s\n" % timespec)
            sts = p.close()
            if sts:
                print "Sendmail exit status", sts

    poa = orb.resolve_initial_references("RootPOA")
    alarm = SendMailAlarm()._this()
    poa._get_the_POAManager().activate()

    factory = oaf.activate("repo_ids.has('IDL:SandUhr/TimerFactory:1.0')",[])
    timer = factory.CreateTimer ("+60s", "The example timer has reached its time")
    timer.Alarm = alarm

    orb.run()

There is another possibility to plug in an alarm action. You can find out the IOR string of your `AlarmAction` object with the help of the `ORB::object_to_string` method. If you fill in this string into the corresponding entry in the action tab of a timer's properties dialog, the timer will deliver the alarm with the help of your server. This is demonstrated by Example 6.

| This technique will come in handy if you use a CORBA language binding where there are no bindings for the OAF library. This library is not needed here.

Example 6. Plugging in CORBA alarm actions via the IOR string

The following Python script implements an example alarm action. If you run this script, it will output an IOR string and then just start sleeping. Fill in this string into the corresponding field of the action tab in a timer's properties dialog. The timer then will call the `Deliver()` action of this script.

    import CORBA, SandUhr, SandUhr__POA

    class Wecker(SandUhr__POA.AlarmAction):
        def __init__(self):
            self.NeedsPopup = CORBA.FALSE

        def Attach(self, timer):
            pass

        def Detach(self, timer):
            orb.shutdown(1)

        def Deliver(self, timespec, message):
            print message

    orb = CORBA.ORB_init()
    poa = orb.resolve_initial_references("RootPOA")

    ref = Wecker()._this()
    print orb.object_to_string(ref)

    poa.the_POAManager.activate()
    orb.run()

Prev | Home | Next
Customisation |  | Authors