Interfacing a Contact-Closure UPS to Mac OS X and Linux

Having acquired some cheap Liebert Powersure Proactive and Powersure Personal UPS boxes, I set about interfacing them to my Mac and Linux machines. In the process I learned a few things about OS X that I didn't know before.

The UPS

Both models of UPS have a 9-way D socket on the back with a basic contact-closure signalling arrangement that allows On Battery and Low Battery to be indicated by the closing of relay contacts. The Proactive uses relays and is polarity-independent whereas the Personal uses solid-state switching and is polarity sensitive. It also assigns a remote-shutdown function to pin 6.

PINFUNCTION
1Low Battery (+)
2Not Used
3Not Used
4UPS Off
5UPS Ground
6On Battery (NC)/Remote Shutdown
7Low Battery (-)
8On Battery (COM) (-)
9On Battery (NO) (+)

The Interconnection Cable

The same interconnection cable is used for interfacing either type of UPS to both a PC running Linux and to a Mac. Note that this is not the same as the MultiLink cable that is often supplied with these UPS. With the settings used elsewhere it provides a positive voltage on pins 9 and 1 via DTR and negative voltages are provided by RTS. When the On Battery condition is present, pins 8 and 9 are shorted, which pulls CTS positive, R2 having previously held it negative. When the Low Battery condition is present, pins 1 and 7 are shorted. This pulls DCD negative, R1 having previously held it positive.

Cable Diagram

Connecting to the Computer

Most PCs will have a spare serial port that can be pressed into service. If not, there are various USB Serial converters that work just as well. I'm using various brands that use the Prolific PL2303 chip which is supported natively by Linux. All modern Macs of which I am aware lack anything remotely resembling a built-in serial port so a USB Serial converter is required. The same PL2303-based solution can be used although an installable driver for OS X is required. I use version 1.09b6 of the driver, although they now appear to have a newer version, including drivers for Intel-based Macs. I haven't tested the newer version, but I've put a copy of what I use here. If you were using an earlier version and have upgraded to OS X 10.4 then you'll need to upgrade the driver as well because 1.06 doesn't appear to work.

Software

For both systems I use the Network UPS Tools software which is available as source and compiles with no problems. I used version 2.0.0 which was the latest stable version at time of writing.
Create a system user nutmon for use with the UPS software.
Next untar the source, change to the nut-2.0.0 directory and run ./configure --with-user=nutmon, followed by make and (as root) make install.
The software gets installed by default to /usr/local/ups and the following assumes this. Config files are found in /usr/local/ups/etc. The Network UPS Tools site is a good start for what it all really means.

Initial Configuration

Most of the config can be derived from the Network UPS Tools site documentation but the ups.conf file has stuff specific to the UPS in use. Comment out everything in the file and add a section:

[liebert]
        driver = genericups
        port = /dev/ttyS0
        upstype = 11
        mfr = Liebert
        model = Powersure Proactive

Adjust the port as appropriate, it may be something like /dev/ttyS1 or /dev/ttyUSB0 for Linux or /dev/tty.usbserial0 for OS X. Note also that in other files, the UPS is referred to as liebert@localhost (or you can change the name in square brackets).

Testing

Initial testing can be done by starting all the daemons by hand. Make sure you have nothing else important in progress because if you get things wrong it may decide that the machine needs to be shut down immediately. Connect the serial cable to the machine serial port. It is not necessary at this point to connect to the UPS.
Start the daemons as root with:

/usr/local/ups/bin/upsdrvctl start
/usr/local/ups/sbin/upsd
/usr/local/ups/sbin/upsmon

They should all come up with no problems if your configuration is correct and the wiring in the serial cable is OK. Next, short pins 8 and 9 on the UPS end of the serial cable. Within a few seconds you should get a broadcast announcement in the root window to the effect that UPS liebert@localhost is on battery. Remove the short and it should tell you that it is back on line power. Next, short pins 1 and 7 and it should tell you that the UPS has a low battery condition. However, removing the short does not tell you that the condition has gone away. To test a proper shutdown procedure, short pins 8 and 9 together. When it reports that the UPS is on battery power, short pins 1 and 7. You should then get a message to the effect that shutdown will commence immediately and your next job will be to switch the machine back on and log in again.

Running Daemons at Startup

The nut tar file contains a scripts directory that can be used with RedHat and adapted for other Linux flavours. For RedHat copy the script to /etc/init.d and then put symbolic links to the file from whichever run level rc?.d directories you want protected.
For OS X it is necessary to navigate to /System/Library/StartupItems. I started by creating a ups directory and copying the contents of another (I used the Samba) directory tree into it. Change to the ups directory and there will be a Resources directory and two files: StartupParameters.plist and Samba. Delete the latter and replace it with a file called ups with this content:

#!/bin/sh


#
# UPS script
#
# David Hough 2004-08-24


NUT_PREFIX=/usr/local/ups

case $1 in
        start  )

        ${NUT_PREFIX}/bin/upsdrvctl start
        ${NUT_PREFIX}/sbin/upsd
        ${NUT_PREFIX}/sbin/upsmon
        touch /var/lock/subsys/upsd
;;

        stop  )

        ${NUT_PREFIX}/sbin/upsmon -c stop
        ${NUT_PREFIX}/sbin/upsd -c stop
        ${NUT_PREFIX}/bin/upsdrvctl stop
        rm -f /var/lock/subsys/upsd
;;

        restart  )

        $0 stop
        $0 start
;;

esac

Edit the StartupParameters.plist file to read:

{
    Description = "UPS Monitor";
    Messages = {start = "Starting UPS Monitor"; stop = "Stopping UPS Monitor"; };
    OrderPreference = None;
    Provides = (UPS);
    Requires = (Resolver);
}

For both Linux and OS X, reboot the system at this point to check whether the daemons start correctly. At a terminal window the command: ps ax | grep ups should produce an output along the lines of:

  431  ??  Ss     0:07.12 /usr/local/ups/bin/genericups -a liebert
  452  ??  Ss     0:09.66 /usr/local/ups/sbin/upsd
  464  ??  Ss     0:00.01 /usr/local/ups/sbin/upsmon
  466  ??  S      0:09.97 /usr/local/ups/sbin/upsmon
  467  ??  Ss     0:10.34 /usr/sbin/cupsd
  903 std  UV+    0:00.00 grep ups

Final Testing

One final test at this point is to plug the serial cable into the UPS and unplug the mains input to the UPS. The system should flip over to battery power and warn you that it is on battery. Leave the system in that condition until the batttery reaches the low threshold, at which point the system should shut down cleanly. Restore the power input to the UPS and reboot. Everything should now work just fine.

OS X and Other UPS Types

Subsequent to the contact-closure exercise I acquired a spare APC SmartUPS and set about interfacing that to the Mac. Given the existing set-up with the Liebert UPS, this proved remarkably easy and was simply a matter of editing ups.conf to load the apcsmart driver (with appropriate options) in place of the generic one, swapping the serial lead for an APC one and restarting the UPS daemons. Other UPS types with existing drivers will probably work equally well.


Comments, corrections or queries to email address
Counter since 28th August 2004
Last modified Sun, 13 Jan 2008 21:06:34 UTC © David Hough