pkg://Linux-HOWTOs.tar.gz:1682658/UPS-HOWTO
downloads
The UPS Howto
Harvey J. Stein, abel@netvision.net.il, Berger Financial Research,
Ltd.
v2.02, 31 March 1997
This document will help you connect an uninterruptable power supply to
a Linux box... if you're lucky... Copyright (c) 1994, 1995, 1996,
1997 by Harvey J. Stein. You may use this document as you see fit, as
long as it remains intact. In particular, this notice (along with the
contributions below) must remain untouched.
1. Introduction
This HOWTO covers connecting a UPS to a computer running Linux. The
idea is to connect the two in such a way that Linux can shutdown
cleanly when the power goes out, and before the UPS's battery gives
out.
This includes pointing out the existence of software packages which
aid in establishing such communications, and detailing exactly how
such communications are carried out. The latter often is unnecessary
if you can find a software package that's already been configured for
your UPS. Otherwise, you'll have to read on.
To a large extent this document is even more redundant than when I
originally wrote it three years ago. All the basic information has
always been contained in the powerd man page that comes with the
SysVinit package. Whereas three years ago one could commonly find
Linux distributions which didn't even include this man page, I don't
believe this is the case any longer.
Furthermore, when I first wrote this Howto, there was no software
other than powerd.c for Linux/UPS communications and control. Today
there are quite afew UPS control packages available in Sunsite's UPS
directory <http://sunsite.unc.edu:/pub/Linux/system/ups>.
None the less, spurred on by RedHat's imminent reprinting of Dr.
Linux, I'm updating the UPS Howto. Why bother? Well,
· An additional general overview might help to understand how to
connect a Linux system to a UPS, even if it's just the same
information written differently.
· The HOWTO is serving as a repository for UPS specific data - there
are many UPSs that haven't yet been incorporated into the general
packages.
· The HOWTO contains additional details that aren't available in
other documents.
· Some of the UPS software packages available in Sunsite's UPS
directory <http://sunsite.unc.edu:/pub/Linux/system/ups> seem to be
quite sparsely documented. You might need to read this before you
can understand how to use them.
· This thing seems to have a life of it's own now. It's clear when a
Howto should be born. It's less clear when it should be put to
sleep.
1.1. Contributors
I am forever indebted to those from whom I've received help,
suggestions, and UPS specific data. The list includes:
· Hennus Bergman (hennus@sky.owl.nl)
· Charli (mefistos@impsat1.com.ar)
· Ciro Cattuto (Ciro Cattuto)
· Nick Christenson (npc@minotaur.jpl.nasa.gov)
· Lam Dang (angit@netcom.com)
· Markus Eiden (Markus@eiden.de)
· Dan Fandrich (dan@fch.wimsey.bc.ca)
· Ben Galliart (bgallia@orion.it.luc.edu)
· Danny ter Haar (dth@cistron.nl)
· Christian G. Holtje (docwhat@uiuc.edu)
· Raymond A. Ingles (inglesra@frc.com)
· Peter Kammer (pkammer@ics.uci.edu)
· Marek Michalkiewicz (ind43@sun1000.ci.pwr.wroc.pl)
· Jim Ockers (ockers@umr.edu)
· Evgeny Stambulchik (fnevgeny@plasma-gate.weizmann.ac.il)
· Clive A. Stubbings (cas@vjet.demon.co.uk)
· Miquel van Smoorenburg (miquels@cistron.nl)
· Slavik Terletsky (ts@polynet.lviv.ua)
· Tom Webster (webster@kaiwan.com)
Note that email addresses appearing below as excerpts from email
messages can be out of date. The above is probably out of date too,
but some of it's more recent than what's below.
Also, many apologies to anyone whom I've failed to note in this list.
Please email me and I'll add you.
1.2. Important disclaimer
I really can't guarantee that any of this will work for you.
Connecting a UPS to a computer can be a tricky business. One or the
other or both might burn out, blow up, catch fire, or start World War
Three. Furthermore, I only have direct experience with the Advice
1200 A UPS, and a 5kva Best Ferrups, and I didn't have to make a
cable. So, BE CAREFUL. GATHER ALL INFORMATION YOU CAN ON YOUR UPS.
THINK FIRST. DON'T IMPLICITLY TRUST ANYTHING YOU READ HERE OR
ANYWHERE ELSE.
On the other hand, I managed to get everything working with my UPSs,
without much information from the manufacturer, and without blowing
anything up, so it is possible.
1.3. Other documents
This document does not cover the general features and capabilities of
UPSs. For that type of information, you might turn to The UPS FAQ
<ftp://navigator.jpl.nasa.gov/pub/doc/faq/UPS.faq>. It can also be
found at ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/answers/UPS-
faq. It is maintained by Nick Christenson
(npc@minotaur.jpl.nasa.gov), but seems to have last been updated in
1995. In email to him, he'd like that you put UPS or UPS FAQ or
something along these lines in the Subject line of the message.
There're also more and more UPS manufactures sprouting up on the net.
Some of them actually supply useful information on their web sites. A
convenient list of UPS manufacturers' web sites is available at The
UPS Directory <http://www.upssystems.uk.com/upsdir.html>. Said site
also has a UPS FAQ <http://www.upssystems.uk.com/upsfaqs.html>.
2. Important note on obsolete information
I've just discovered that some of the documentation below is obsolete.
In particular, the init daemon that comes with the latest sysvinit
package
<http://sunsite.unc.edu/pub/Linux/system/daemons/init/sysvinit-2.64.tar.gz>
is more sophisticated than I've portrayed it to be. Although it seems
that the current version is backward compatible with what's written
here, it looks like it has some undocumented features which are very
important for UPS support.
The control mechanism outlined below only allows powerd to give init
one of two messages, namely powerfail or powerok. init runs one
command when it receives powerfail, and another when it receives
powerok. This leads to complicated powerd logic for dealing with low
battery signals and other sorts of special situations.
Newer versions of init (as of version 2.58, it seems) are more
sophisticated. These versions can be signaled to run one of three
scripts. Thus, init can have a powerfail script for announcing a
power outage, a powerfailnow script for doing an immediate shutdown,
and a powerok script for halting any pending shutdowns. This is much
cleaner than the gyrations one would have to go through with the
mechanisms detailed below.
Although most of the discussion here assumes the old init
communication method, I just added two new sections where the authors
uses the new communcation method. These are sections ``Trust Energy
Protector 400/650'' and ``APC Smart-UPS 700''. The former is
especially detailed. Both include a powerd.c which signals init to do
an immediate shutdown when a low battery signal is received, as well
as the relevant /etc/inittab lines to make this work. Other than
this, all I can tell you is to look at the source code for init.
Also, for all I know, many of the software packages listed below also
use this newer communication method.
3. Smart and dumb UPSs.
UPSs fall into two categories, which I'll call ``smart'' and ``dumb''.
The difference between the two is the amount of information one can
get from the UPS and the amount of control one can exert over the UPS.
Dumb UPS
· Connects to the computer via serial port.
· Uses modem control lines to communicate with the computer.
· Can signal whether or not the power is out.
· Typically can signal whether or not the battery is low.
· The computer can usually signal the UPS to turn itself off.
Smart UPS
· Connects to the computer via serial port.
· Communicates with the computer via normal data transfer through
the serial port.
· Typically has some sort of command language that the computer
can use to get various pieces of information from the UPS, to
set various operating parameters for the UPS, and to control the
UPS (such as turning it off).
Usually smart UPSs can be operated in dumb mode. This is useful
because as far as I know, the company which manufactures the most
popular smart UPS (namely APC) will only disclose the communication
protocol for their UPSs to people who sign a non-disclosure agreement.
As far as I know, the only smart UPS available which is easy to
communicate with under Linux are those made by Best. Furthermore,
BEST fully documents the smart mode (and the dumb mode) of their UPSs.
BEST also supplies source code for programs which can communicate with
their UPSs.
All the packages listed in section ``Software'' will communicate with
a UPS in dumb mode. This is all you really need. The ones
specifically for the APC UPSs make various claims as to being usable
in smart mode, but I don't know exactly what they permit. A full
implementation would give you a pop-up window with all sorts of fun
gauges displaying various statistics for the UPS, such as load,
internal temperature, fault history, input voltage, output voltage,
etc. It seems like the smupsd-0.7-1.i386.rpm package (section
``Software'') approaches this. I'm not sure about the others.
The rest of this document is pretty much confined to configuring your
system to work with a dumb UPS. The general idea is about the same
with a smart UPS, but the details of how powerd would need to work and
what kind of cable you need are different for a smart UPS.
4. Software
Basically, all you need is a working powerd binary, usually found in
/sbin/powerd. This is usually part of the SysVinit package. As far
as I know, all current Linux distributions include a recent version of
SysVinit. Very old versions didn't include powerd.
The only problem you might have is that your cable might not match how
powerd is set up, in which case you'll have to either rewire your
cable, or pick up a copy of powerd.c and modify it to work with your
cable. Or, for that matter, you can always pick up one of the
following packages, most of which allow you to configure them to match
your cable.
As mentioned, an alternative to using the powerd that comes with the
SysVinit package would be to use one of the UPS packages now
available. There are many packages currently available to aid in
setting up computer/ups communications. None of this was available
when I first wrote this Howto, which is why I had to write it. In
fact, there's a good chance that you might be able to use one of these
software packages, and avoid this Howto entirely!
As of 15 March 1997 or so, Sunsite's UPS directory
<http://sunsite.unc.edu:/pub/Linux/system/ups> had quite a few
packages available. Other sites seem to have UPS control packages
available too. Here's what I've found to date (all but two from
sunsite):
Enhanced_APC_BackUPS.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/Enhanced_APC_BackUPS.tar.gz>
A package for controlling APC Smart UPSs. Seems to basically
follow the BUPS Howto (included here), but also seems to have
some low battery warning support.
Enhanced_APC_UPSD-v1.4.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/Enhanced_APC_UPSD-
v1.4.tar.gz>
The .lsm file says that it's formerly the above package, but it
actually includes the above package as a .tar.gz file inside of
this tar.gz file! The documentation is spotty. It seems to
support APC UPSs in both smart mode and dumb mode, but I can't
be sure.
apcd-0.5.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/apcd-0.5.tar.gz>
Another package for controlling APC Smart UPSs. Seems to
include some sort of master/slave support (i.e. - one machine
signals others to shut down when the power goes out). Seems to
use the UPS in smart mode, as opposed to via modem signal line
toggling.
smupsd directory <ftp://cms180.cmsnet.com/pub/smupsd/>
Yet another package for APC UPSs. Seems to operate APC UPSs in
Very Smart(tm) mode. For example, it includes a Java based GUI
UPS monitoring tool! The above directory includes the software
package precompiled in RPM package format
(ftp://cms180.cmsnet.com/pub/smupsd/smupsd-0.7-1.i386.rpm), as
well as a source RPM for the package
(ftp://cms180.cmsnet.com/pub/smupsd/smupsd-0.7-1.src.rpm), and a
readme for the package
(ftp://cms180.cmsnet.com/pub/smupsd/smupsd-0.7-1.README).
genpower-1.0.1.tgz
<http://sunsite.unc.edu:/pub/Linux/system/ups/genpower-1.0.1.tgz>
A general UPS handling package. Includes configurations for
many UPSs - two TrippLite configurations, and three APC
configurations. Includes good documentation. A best buy.
powerd-2.0.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/powerd-2.0.tar.gz>
A replacement for the powerd that comes with the SysVinit
package. As opposed to comments included in the documentation
it doesn't seem to have been merged into the SysVinit package as
of version 2.62. Its advantages are that it can act as a server
for other powerds running on other machines (for when you have a
network of machines hanging off a single UPS), and it can be
configured by config file - the source code doesn't have to be
edited and recompiled.
upsd-1.0.tgz
<http://sunsite.unc.edu:/pub/Linux/system/ups/upsd-1.0.tgz>
Another replacement for powerd. Seems to be quite comparable in
features to powerd-2.0.tar.gz.
checkups.tar
<http://www.bestpower.com/section/software/checkups.tar>
This package is for controlling Best UPSs. It's direct from
Best's web site. Includes binaries for lots of unix flavors,
but more importantly, it includes source code, so you can try it
out under Linux, and if it doesn't work, you can try to fix it.
The source code includes both ``basic checkups'' which controls
the UPS in dumb mode, and ``advanced checkups'' which is a
little more sophisticated - it will signal a shutdown when the
UPS says it has X minutes of power remaining instead of just
shutting down X minutes after the power goes out. The advanced
checkups program also will shut down when the UPS registers
various alarms such as High Ambient Temperature, Near Low
Battery, Low AC Out, or User Test Alarm.
bestups-0.9.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/bestups-0.9.tar.gz>
A package that might very well be on sunsite by the time you
read this. It's a pair of communications module which works
with Best Ferrups UPSs. It operates the UPS in smart mode. It
inter-operates well with powerd-2.0 - useful if you have a big
Best Ferrups UPS keeping up all the machines on a network.
Note that I've only glanced at these packages. I haven't used them,
except that we've just started using bestups-0.9.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/bestups-0.9.tar.gz> in
conjunction with powerd-2.0.tar.gz
<http://sunsite.unc.edu:/pub/Linux/system/ups/powerd-2.0.tar.gz>,
where ``just started'' means we began testing last Thursday.
5. Do it yourself guide
This discussion is specifically tailored for dumb UPS control.
However, most of the process is about the same for dumb UPSs and smart
UPSs. The biggest difference is in the details of how the UPS
monitoring daemon (typically powerd) communicates with the UPS.
Before doing anything, I suggest the following algorithm:
· Skim this document.
· Download and investigate all packages which seem specifically
tailored to your UPS.
· Download and investigate the more generic packages. Note that some
of the more generic packages are actually more powerful, better
documented, and easier to use than their more specific
counterparts.
· If you still can't get things working, or if points are still
unclear, read this document more carefully, and hack away...
5.1. What you need to do (summary)
· Plug the computer into the UPS.
· Connect the computer's serial port to the UPS with a special cable.
· Run powerd (or some sort of equivalent) on the computer.
· Setup your init to do something reasonable on powerfail and powerok
events (like start a shutdown and kill any currently running
shutdowns, respectively, for example).
5.2. How it's supposed to work
UPS's job
When the power goes out, the UPS continues to power the computer
and signals that the power went out by throwing a relay or
turning on an opticoupler on it's control port.
Cable's job
The cable is designed so that when the UPS throws said relay,
this causes a particular serial port control line (typically
DCD) to go high.
Powerd's job
The powerd daemon monitors the serial port. Keeps
raised/lowered whatever serial port control lines the UPS needs
to have raised/lowered (typically, DTR must be kept high and
whatever line shuts off the UPS must be kept low). When powerd
sees the UPS control line go high, it writes FAIL to
/etc/powerfail and sends the init process a SIGPWR signal. When
the control line goes low again, it writes OK to /etc/powerfail
and sends init a SIGPWR signal.
Init's job (aside from everything else it does)
When it receives a SIGPWR, it looks at /etc/powerfail. If it
contains FAIL it runs the powerfail entry from /etc/inittab. If
it contains OK it runs the powerokwait entry from inittab.
5.3. How to set things up
The following presupposes that you have a cable that works properly
with powerd. If you're not sure that your cable works (or how it
works), see section ``Reverse-engineering cables and hacking
powerd.c'' for information on dealing with poorly described cables and
reconfiguring powerd.c. Sections ``Serial port pin assignments'' and
``Ioctl to RS232 correspondence'' will also be useful.
If you need to make a cable, see section ``How to make a cable'' for
the overall details, and the subsection of section ``Info on selected
UPSs'' that refers to your UPS. The latter might also include
information on manufacturer supplied cables. You may want to at least
skim all of section ``Info on selected UPSs'' because each section has
a few additional generally helpful details.
· Edit /etc/inittab. Put in something like this:
# What to do when power fails (Halt system & drain battery :):
pf::powerfail:/etc/powerfailscript +5
# If power is back before shutdown, cancel the running shutdown.
pg:0123456:powerokwait:/etc/powerokscript
· Write scripts /etc/powerfailscript and /etc/powerokscript to
shutdown in 5 minutes (or whatever's appropriate) and kill any
existing shutdown, respectively. Depending on the version of
shutdown that you're using, this will be either so trivial that
you'll dispense with the scripts, or be a 1 line bash script,
something along the lines of:
kill `ps -aux | grep "shutdown" | grep -v grep | awk '{print $2}'`
and you'll keep the scripts. (In case it doesn't come out right, the
first single quote on the above line is a backquote, the second and
third are single quotes, and the last is also a backquote.)
· Tell init to re-process the inittab file with the command:
telinit q
· Edit rc.local so that powerd gets run upon startup. The syntax is:
powerd <line>
Replace <line> with the serial port that the modem is connected, such
as /dev/cua1.
· Connect computer's serial port to UPS's serial port. DO NOT PLUG
THE COMPUTER INTO UPS YET.
· Plug a light into the UPS.
· Turn on the UPS and the light.
· Run powerd.
· Test the setup:
· Yank the UPS's plug.
· Check that the light stays on.
· Check that /etc/powerfailscript runs.
· Check that shutdown is running.
· Plug the UPS back in.
· Check that the light stays on.
· Check that /etc/powerokscript runs.
· Check that /etc/powerfailscript is not running.
· Check that shutdown is no longer running.
· Yank the UPS's plug again. Leave it out and make sure that the
computer shuts down properly in the proper amount of time.
· The Dangerous Part. After everything seems to be proper, power down
the computer and plug it into the UPS. Run a script that sync's
the hard disk every second or so. Simultaneously run a second
script that keeps doing a find over your entire hard disk. The
first is to make this a little safer and the second is to help draw
lots of power. Now, pull the plug on the UPS, check again that
shutdown is running and wait. Make sure that the computer shuts
down cleanly before the battery on the UPS gives out. This is
dangerous because if the power goes out before the computer shuts
down, you can end up with a corrupt file system, and maybe even
lose all your files. You'll probably want to do a full backup
before this test, and set the shutdown time extremely short to
begin with.
Congratulations! You now have a Linux computer that's protected by a
UPS and will shutdown cleanly when the power goes out!
5.4. User Enhancements
· Hack powerd.c to monitor the line indicating that the batteries are
low. When the batteries get low, do an immediate shutdown.
· Modify the shutdown procedure so that if it's shutting down in a
powerfail situation, then it turns off the UPS after doing
everything necessary.
6. Hardware notes
6.1. How to make a cable
This section is just from messages I've seen on the net. I haven't
done it so I can't write from experience. If anyone has, please write
this section for me :). See also the message about the GPS1000
contained in section ``GPS1000 from ACCODATA'', not to mention all the
UPS specific data in section ``Info on selected UPSs''.
>From miquels@caution.cistron.nl.mugnet.org Wed Jul 21 14:26:33 1993
Newsgroups: comp.os.linux
Subject: Re: UPS interface for Linux?
From: miquels@caution.cistron.nl.mugnet.org (Miquel van Smoorenburg)
Date: Sat, 17 Jul 93 18:03:37
Distribution: world
Organization: Cistron Electronics.
In article <1993Jul15.184450.5193@excaliber.uucp>
joel@rac1.wam.umd.edu (Joel M. Hoffman) writes:
>I'm in the process of buying a UPS (Uninteruptable Power Supply), and
>notice that some of them have interfaces for LAN's to signal the LAN
>when the power fails.
>
>Is there such an interface for Linux?
>
>Thanks.
>
>-Joel
>(joel@wam.umd.edu)
>
When I worked on the last versioon of SysVinit (Now version 2.4),
I temporarily had a UPS on my computer, so I added support for it.
You might have seen that in the latest <signal.h> header files there
is a #define SIGPWR 30 now :-). Anyway, I did not have such a special
interface but the output of most UPS's is just a relais that makes or breaks
on power interrupt. I thought up a simple way to connect this to the
DCD line of the serial port. In the SysVinit package there is a daemon
called 'powerd' that keeps an eye on that serial line and sends SIGPWR
to init when the status changes, so that init can do something (such as
bringing the system down within 5 minutes). How to connect the UPS to
the serial line is described in the source "powerd.c", but I will
draw it here for explanation:
+------------------------o DTR
|
+---+
| | resistor
| | 10 kilo-Ohm
| |
+---+ To serial port.
|
+-----o-------+------------------------o DCD
| |
o UPS |
\ relais |
\ |
| |
+-----o-------+------------------------o GND
Nice drawing eh?
Hope this helps.
SysVinit can be found on sunsite (and tsx-11 probably) as
SysVinit2.4.tar.z
Mike.
--
Miquel van Smoorenburg, <miquels@cistron.nl.mugnet.org>
Ibmio.com: cannot open CONFIG.SYS: file handle broke off.
>From danny@caution.cistron.nl.mugnet.org Wed Jul 21 14:27:04 1993
Newsgroups: comp.os.linux
Subject: Re: UPS interface for Linux?
From: danny@caution.cistron.nl.mugnet.org (Danny ter Haar)
Date: Mon, 19 Jul 93 11:02:14
Distribution: world
Organization: Cistron Electronics.
In article <9307174330@caution.cistron.nl.mugnet.org>
miquels@caution.cistron.nl.mugnet.org (Miquel van Smoorenburg) writes:
>How to connect the UPS to the serial line is described in the source
>"powerd.c", but I will draw it here for explanation:
The drawing wasn't really clear, please use this one in stead !
>
> +------------------------o DTR
> |
> +---+
> | | resistor
> | | 10 kilo-Ohm
> | |
> +---+ To serial port.
> |
> +-----o-------+------------------------o DCD
> |
> o UPS
> \ relais
> \
> |
> +-----o--------------------------------o GND
>
The DTR is kept high, when the UPS's power input is gone it
will close the relais . The computer is monitoring
the DCD input port to go LOW . When this happens it will start a
shutdown sequence...
_____
Danny
--
<=====================================================================>
Danny ter Haar <dannyth@hacktic.nl> or <danny@cistron.nl.mugnet.org>
Robins law #103: 'a couple of lightyears can't part good friends'
6.2. Reverse-engineering cables and hacking powerd.c
Try to get documentation for the cables that your UPS seller supplies.
In particular find out:
· What lines need to be kept high.
· What line(s) turn off the UPS.
· What lines the UPS toggles to indicate that:
· Power is out.
· Battery is low.
You then need to either hack powerd.c appropriately, or use one of the
above configurable packages (see the packages genpower-1.0.1.tgz,
powerd-2.0.tar.gz, or upsd-1.0.tgz described in section ``Software'').
If you use one of the packages, follow the instructions there. If you
want to hack powerd.c, keep reading.
If you have trouble getting the above information, or just want to
check it (a good idea) the following program might help. It's a
hacked version of powerd.c. It allows you to set the necessary port
flags from the command line and then monitors the port, displaying the
control lines every second. I used it as ``upscheck /dev/cua1 2''
(for example) to set the 2nd bit (DTR) and to clear the other bits.
The number base 2 indicates which bits to set, so for example to set
bits 1, 2 and 3, (and clear the others) use 7. See the code for
details.
Here's the (untested) upscheck.c program. It's untested because I
edited the version I originally used to make it clearer, and can't
test the new version at the moment.
/*
* upscheck Check how UPS & computer communicate.
*
* Usage: upscheck <device> <bits to set>
* For example, upscheck /dev/cua4 4 to set bit 3 &
* monitor /dev/cua4.
*
* Author: Harvey J. Stein <hjstein@math.huji.ac.il>
* (but really just a minor modification of Miquel van
* Smoorenburg's <miquels@drinkel.nl.mugnet.org> powerd.c
*
* Version: 1.0 19940802
*
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
/* Main program. */
int main(int argc, char **argv)
{
int fd;
/* These TIOCM_* parameters are defined in <linux/termios.h>, which */
/* is indirectly included here. */
int dtr_bit = TIOCM_DTR;
int rts_bit = TIOCM_RTS;
int set_bits;
int flags;
int status, oldstat = -1;
int count = 0;
int pc;
if (argc < 2) {
fprintf(stderr, "Usage: upscheck <device> <bits-to-set>\n");
exit(1);
}
/* Open monitor device. */
if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
fprintf(stderr, "upscheck: %s: %s\n", argv[1], sys_errlist[errno]);
exit(1);}
/* Get the bits to set from the command line. */
sscanf(argv[2], "%d", &set_bits);
while (1) {
/* Set the command line specified bits (& only the command line */
/* specified bits). */
ioctl(fd, TIOCMSET, &set_bits);
fprintf(stderr, "Setting %o.\n", set_bits);
sleep(1);
/* Get the current line bits */
ioctl(fd, TIOCMGET, &flags);
fprintf(stderr, "Flags are %o.\n", flags);
/* Fiddle here by changing TIOCM_CTS to some other TIOCM until */
/* this program detects that the power goes out when you yank */
/* the plug on the UPS. Then you'll know how to modify powerd.c. */
if (flags & TIOCM_CTS)
{
pc = 0 ;
fprintf(stderr, "power is up.\n");
}
else
{
pc = pc + 1 ;
fprintf(stderr, "power is down.\n");
}
}
close(fd);
}
6.3. Serial port pin assignments
The previous section presupposes knowledge of the correspondence
between terminal signals and serial port pins. Here's a reference for
that correspondence, taken from David Tal's ``Frequently Used Cables
and Connectors'' document. I'm including a diagram illustrating the
connectors, and a table listing the correspondence between pin numbers
and terminal line signals.
If you need a general reference for cable wiring, connectors, etc,
then David Tal's would be a good one, but I can't seem to locate this
document on the net any more. But I've found a good replacement.
It's The Hardware Book <http://www.blackdown.org/~hwb/hwb.html>.
Other useful sites:
· Yost Serial Device Wiring Standard
<http://star.sols.pt/docs/yost.html> which contains interesting
information on how to use RJ-45 jacks and eight wire cables for all
serial port connections.
· Stokely Consulting <http://www.stokely.com/stokely> for general
Unix info, and in particular their Unix Serial Port Resources.
· Unix Workstation System Administration Education Certification
<http://www.uwsg.indiana.edu/usail/edcert/> which contains RS-232:
Connectors and Cabling
<http://www.uwsg.indiana.edu/usail/peripherals/serial/rs232/>
Incidentally, it seems that the Linuxdoc-sgml package still doesn't
format tables very well in the html output. If you want to be able to
read the following table, you're probably going to have to look at
either the DVI version or the plain text version of this document.
| | | | | | | |
|DB-25 | DB-9 | Name | EIA | CCITT | DTE-DCE | Description |
|Pin # | Pin # | | | | | |
|________|_________|_________|________|__________|___________|_______________ |
|1 | | FG | AA | 101 | --- | Frame Ground/Chassis GND |
|2 | 3 | TD | BA | 103 | ---> | Transmitted Data, TxD |
|3 | 2 | RD | BB | 104 | <--- | Received Data, RxD |
|4 | 7 | RTS | CA | 105 | ---> | Request To Send |
|5 | 8 | CTS | CB | 106 | <--- | Clear To Send |
|6 | 6 | DSR | CC | 107 | <--- | Data Set Ready |
|7 | 5 | SG | AB | 102 | ---- | Signal Ground, GND |
|8 | 1 | DCD | CF | 109 | <--- | Data Carrier Detect |
|9 | | -- | -- | - | - | Positive DC test voltage |
|10 | | -- | -- | - | - | Negative DC test voltage |
|11 | | QM | -- | - | <--- | Equalizer mode |
|12 | | SDCD | SCF | 122 | <--- | Secondary Data Carrier Detect |
|13 | | SCTS | SCB | 121 | <--- | Secondary Clear To Send |
|14 | | STD | SBA | 118 | ---> | Secondary Transmitted Data |
|15 | | TC | DB | 114 | <--- | Transmitter (signal) Clock |
|16 | | SRD | SBB | 119 | <--- | Secondary Receiver Clock |
|17 | | RC | DD | 115 | ---> | Receiver (signal) Clock |
|18 | | DCR | -- | - | <--- | Divided Clock Receiver |
|19 | | SRTS | SCA | 120 | ---> | Secondary Request To Send |
|20 | 4 | DTR | CD | 108.2 | ---> | Data Terminal Ready |
|21 | | SQ | CG | 110 | <--- | Signal Quality Detect |
|22 | 9 | RI | CE | 125 | <--- | Ring Indicator |
|23 | | -- | CH | 111 | ---> | Data rate selector |
|24 | | -- | CI | 112 | <--- | Data rate selector |
|25 | | TC | DA | 113 | <--- | Transmitted Clock |
Pin Assignment for the Serial Port (RS-232C), 25-pin and 9-pin
1 13 1 5
_______________________________ _______________
\ . . . . . . . . . . . . . / \ . . . . . / RS232-connectors
\ . . . . . . . . . . . . / \ . . . . / seen from outside
--------------------------- ----------- of computer.
14 25 6 9
DTE : Data Terminal Equipment (i.e. computer)
DCE : Data Communications Equipment (i.e. modem)
RxD : Data received; 1 is transmitted "low", 0 as "high"
TxD : Data sent; 1 is transmitted "low", 0 as "high"
DTR : DTE announces that it is powered up and ready to communicate
DSR : DCE announces that it is ready to communicate; low=modem hangup
RTS : DTE asks DCE for permission to send data
CTS : DCE agrees on RTS
RI : DCE signals the DTE that an establishment of a connection is attempted
DCD : DCE announces that a connection is established
6.4. Ioctl to RS232 correspondence
Since you also might need to modify powerd.c to raise and lower the
correct lines, you might also need the numeric values of different
terminal signals. The can be found in /usr/include/linux/termios.h,
but are reproduced here for reference. Since they could change,
you're best off confirming these values against said file.
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
#define TIOCM_RTS 0x004
#define TIOCM_ST 0x008
#define TIOCM_SR 0x010
#define TIOCM_CTS 0x020
#define TIOCM_CAR 0x040
#define TIOCM_RNG 0x080
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
Note that the 3rd column is in Hex.
7. What to do when you're really stuck
Here's a novel solution to UPS control for when the UPS and the
computer just aren't on speaking terms. I must say that every time I
read this, I'm struck by how clever a solution it is.
From: " Raymond A. Ingles" <inglesra@frc.com>
To: hjstein@math.huji.ac.il
Subject: UPS HOWTO tip
Date: Mon, 24 Feb 1997 11:48:32 -0500 (EST)
I don't know if others would find this useful, but I thought I might
pass this along for possible inclusion in the HOWTO. Thanks for
maintaining a HOWTO that I found very useful!
-----------------
My fiancee bought me a UPS as a present, a Tripp-Lite 400, I believe. It
was very welcome and seems to operate as expected, but unfortunately
doesn't have a serial interface to let the computer know the line power
has failed. It's apparently intended for home or office use where the
computer will not be left unattended.
This, of course, was unacceptable and I began working on a line monitor,
planning on opening up the case and figuring out how to add the hardware
that the manufacturer had left out. Then I realized that there was a
quicker and simpler and cheaper (if somewhat less functional) way.
I had an old 2400 baud modem that I wasn't using, and hooked it up to an
unused serial port on my computer. I then plugged the modem into a surge
supressor plugged into the wall power. I set up powerd with the options
as follows:
-----
serialline /dev/ttyS1
monitor DCD
failwhen low
-----
Now, when the wall power fails (or, since that hasn't happened lately,
when I pull the surge supressor from the wall to test this setup) the modem
fails but the UPS starts supplying power to the computer. When powerd
notices the modem has dropped DCD, it triggers the powerfail sequence.
Obviously, this has some limitations. You can't tell from the modem when
the battery is low and so on. You can only tell that the wall power has
failed. Still, it's certainly cheap and I hate to see functioning
computer equipment lie unused. These days you should be able to get a
2400 baud modem for very nearly free.
I'd still suggest getting a real UPS with full communication capability.
But if you're stuck with a less-functional one, this may at least make it
useful.
Sincerely,
Ray Ingles (810) 377-7735 inglesra@frc.com
"Anybody who has ever seen a photograph showing the kind of damage that
a trout traveling that fast can inflict on the human skull knows that
such photographs are very valuable. I paid $20 for mine." - Dave Barry
8. Info on selected UPSs
This section contains UPS specific information. What I'd like is to
have the UPS control port information (what each pin does and needs to
have done), information on the manufacturer supplied cable (what it
connects where), and a hacked version of powerd.c which works with the
UPS. What I currently have is fairly complete descriptions of setting
up each UPS. I'd try to distill out the relevant information, but
since I can't test each UPS, it's hard to decide exactly what's
relevant. Furthermore, each UPS seems to have some additional quirks
that are nicely described by the authors of each section. So for now
I'm leaving everything in. Makes for a hefty Howto.
Please send me your experiences for inclusion here.
8.1. General Experiences.
I've been saving peoples comments, but haven't gotten permission yet
to include them here. Here's a general summary of what I've heard
from people.
APC: Won't release info on their smart mode without your signature on
a non-disclosure agreement. Thus, people are forced to run their
smart UPSs in the dumb mode as outlined above. Various people have
had varying amounts of success reverse engineering
Best: Helpful and friendly. Supply source code and documentation both
for dumb modes and smart modes.
TrippLite: One person reported that TrippLite won't release info
either.
Upsonic: One person reported that Upsonic has discussed technical
details over the phone, answered questions via fax and are generally
helpful.
8.2. Advice 1200 A
UPS from Advice Electronics, Tel Aviv Israel (they stick their own
name on the things).
I don't recommend them. Our experiences with them have been very bad.
We've twice had a 17" monitor fry when the power failed. We've had
computers spontaneously reboot when the power failed.
None the less, for completeness, here's he UPS Control Port's pin
specifications.
· 2 - Power Fail.
· 5 - Battery Low.
· 6 - Shut Down UPS.
· 4 - Common ground for pin 2, 5, 6.
They also gave me the following picture which didn't help me, but may
help you if you want to build a cable yourself:
2 ----------+
|
\
\|
|--------------
/|
\/ <--- The "\/" here indicates the type of
| this transister. I forget what
| denotes what, but this one points
+-----+ away from the center line.
/ / /
5 ----------+
|
\
\|
|--------------
/|
\/
|
|
+-----+
/ / /
+-------------
|
/
10K |/
6 --\/\/\/--|
|\
\/
|
|
+-----+
/ / /
4 ----------+
|
|
+-----+
/ / /
Cable supplied
They first gave me a cable that was part of a DOS UPS control package
called RUPS. I used this for testing. When I was satisfied, they
gave me a cable they use for Netware servers connected to UPSs. It
functioned identically. Here are the details:
· DTR - Powers cable (make powerd.c keep it high).
· CTS - Power out (stays high and goes low when power goes out).
· DSR - Battery low (stays high. Goes low when battery does).
· RTS - Turns off UPS (keep it low. Set it high to turn off UPS).
(The powerd.c that comes with SysVinit set or left RTS high, causing
the UPS to shut off immediately when powerd was started up!)
8.3. Trust Energy Protector 400/650
This section is good for more than just the Trust Energy Protector.
It illustrates how to work with the new features of init.
How to use a Trust Energy Protector 400/650 under Linux
by Ciro Cattuto <mailto:ciro@stud.unipg.it>
Version 1.0 - 31 March 1997
8.3.1. The computer to UPS connection
The Trust Energy Protector 400/650 is equipped with a remote signal
port. Using a properly designed cable, it is possible to connect the
UPS port to the serial port of a computer, thus making it aware of
power failure events.
8.3.1.1. The UPS signal port
These are the pin assignments for the DB-9 signal port of the Trust
Energy Protector 400/650, as described in the user's manual:
pin 2
The relay will close when input power fails.
pin 4
Common for pins 2 and 5.
pin 5
The relay will close when the battery inside the Trust Energy
Protector 400/650 has less than 1.5 minutes of backup time left.
pin 6
The user may send a high level signal (+5V - +12V) for over 1ms
to turn off the Trust Energy Protector 400/650. However this
option can only be activated when the input power fails.
pin 7
Common for pin 6.
8.3.1.2. The Cable
This is the cable I used to connect the UPS to the serial port of my
computer:
computer side (DB-25) UPS side (DB-9)
===================================================
6 DSR --+ [R] = 10 kilo-Ohm resistor
|
20 DTR --+----+
| |
[R] [R] +--- 7
| | |
8 DCD --+----|----------- ---------|--- 2
| |
7 GND -------|----------- ---------+--- 4
| ....
5 CTS -------+----------- ------------- 5
2 TX ------------------- ------------- 6
===================================================
In the case of a DB-9 serial port, the pins 6,20,8,7,5,2 are mapped to
pins 6,4,1,5,8,3.
8.3.1.3. How the cable works
The computer raises DTR and checks whether DSR is high, to ensure that
the cable is connected to the computer. While the power is good, DCD
and CTS are both high (because of the pull-up resistors).
When the power fails, the relay between pins 2 and 4 of the UPS port
closes, and DCD becomes low, signalling the failure condition.
Similarly, when the UPS batteries are getting low, the relay between
pins 5 and 4 closes, thus lowering CTS.
During a power failure the computer is able to turn off the UPS by
raising TX for over 1ms. This can be easily accomplished sending a
0xFF byte to the serial port, at a low baud rate.
8.3.2. The powerd daemon
To make use of the information available at the serial port we need to
run a program which monitors the port, decodes the signals and sends
the appropriate messages to the operating system, i.e. to the init
process. The init process can execute scripts and programs designed
to handle (gracefully!) the power failure event.
8.3.2.1. Compiling powerd
In Appendix A you'll find the source code of powerd, the daemon I use
to monitor the Trust Energy Protector 400/650. To compile it you will
need the source code of the sysvinit package (I used the code from
sysvinit-2.60). Just overwrite the original powerd.c and compile it.
8.3.2.2. How powerd works
As soon as powerd starts it opens the serial device connected to the
UPS and forces DTR high. It then forks a daemon and exits, leaving the
daemon running. The powerd daemon can be in one of three states:
State 0 - POWER IS GOOD
In this state powerd reads the serial port every T0_SLEEP
seconds (see the #define lines at the beginning of the code).
If DCD drops, powerd switches to state 1. If CTS drops powerd
switches to state 2 (this shouldn't happen without DCD dropping
before, but I decided to stay on the safe side).
State 1 - POWER FAILURE
A power failure was detected. DCD is low and powerd reads the
UPS port every T1_SLEEP seconds. If DCD becomes high, it
switches to state 0. If CTS drops, it switches to state 2.
State 2 - POWER CRITICAL
UPS batteries are low. The powerd daemon will remain in this
state.
Each time powerd changes state, it notifies the init process, so that
the appropriate action can be taken. These events are logged using the
system logging facility.
If DSR is low there must be something wrong with the cable. Powerd
keeps monitoring the DSR line, and every two minutes sends a warning
message to the system logging facility.
8.3.2.3. Running powerd
The powerd daemon should be launched from the system initialization
scripts, during system startup. I added the following lines to my
/etc/rc.d/rc.local script:
# Add support for the UPS
echo "Starting powerd daemon..."
rm -f /etc/turnUPSoff
stty -crtscts speed 75 < /dev/cua3 > /dev/null
if [ -x /usr/sbin/powerd ]; then
/usr/sbin/powerd /dev/cua3
fi
First we remove (if present) the file /etc/turnUPSoff. This file is
used by the system shutdown script (/etc/rc.d/rc.0, in my case) to
decide whether we want to turn the UPS off. See later in this
document for more information.
Then we disable hardware flow control on the serial device connected
to the UPS, and set its baud rate to 75. Now we're confident that the
TX signal will stay high for a time long enough to turn the UPS off,
if we send a character to the serial port (again, see later).
Finally we launch the powerd daemon, specifying the serial port to
monitor. Notice that we're not going to read characters from the
serial device, so don't worry if you have interrupt conflicts -
they'll do no harm.
8.3.3. The inittab file and the shutdown scripts
The powerd process is now running, and it will send signals to init
whenever a power failure occurs. Now we have to configure the system
so that it can react in a useful way when those signals are received.
8.3.3.1. Modifying inittab
Add the following lines near the beginning of your /etc/inittab file:
# What to do when power fails (delayed shutdown).
pf::powerfail:/etc/powerfail_script
# If power is back before shutdown, cancel the runni