Desc: Contact closure hardware
File: contact-closure.txt
Date: 14 March 2004
Auth: Russell Kroll <rkroll@exploits.org>

This is a collection of notes that apply to contact closure UPS
hardware, specifically those monitored by the genericups driver.

Definitions
-----------

"Contact closure" refers to a situation where one line is connected to
another inside UPS hardware to indicate some sort of situation.  These
can be relays, or some other form of switching electronics.  The generic
idea is that you either have a signal on a line, or you don't.  Think
binary.

Usually, the source for a signal is the host PC.  It provides a high
(logic level 1) from one of its outgoing lines, and the UPS returns it
on one or more lines to communicate.  The rest of the time, the UPS
either lets it float or connects it to the ground to indicate a 0.

Other equipment generates the high and low signals internally, and does
not require cable power.  These signals just appear on the right lines
without any special configuration on the PC side.

Bad levels
----------

Some evil cabling and UPS equipment uses the transmit or receive lines
as their reference points for these signals.  This is not sufficient to
register as a high signal on many serial ports.  If you have problems
reading certain signals on your system, make sure your UPS isn't trying
to do this.

Signals
-------

Unlike their smarter cousins, this kind of UPS can only give you very
simple yes/no answers.  Due to the limited number of serial port lines
that can be used for this purpose, you typically get two pieces of data:

	1. "On line" or "on battery"
	2. "Battery OK" or "Low battery"

That's it.  Some equipment actually swaps the second one for a
notification about whether the battery needs to be replaced, which makes
life interesting for those users.

Most hardware also supports an outgoing signal from the PC which means
"shut down the load immediately".  This is generally implemented in such
a way that it only works when running on battery.  Most hardware or
cabling will ignore the shutdown signal when running on line power.

New genericups types
--------------------

If none of the existing types in the genericups driver work completely,
make a note of which ones (if any) manage to work partially.  This can
save you some work when creating support for your hardware.

Use that information to create a list of where the signals from your UPS
appear on the serial port at the PC end, and whether they are active
high or active low.  You also need to know what outgoing lines, if any,
need to be raised in order to supply power to the contacts.  This is
known as cable power.  Finally, if your UPS can shut down the load, that
line must also be identified.

There are only 4 incoming and 2 outgoing lines, so not many combinations
are left.  The other lines on a typical 9 pin port are transmit,
receive, and the ground.  Anything trying to do a high/low signal on
those three is beyond the scope of the genericups driver.  The only
exception is an outgoing BREAK, which we already support.

When editing the genericups.h, the values have the following meanings:

Outgoing lines:

line_norm = what to set to make the line "normal" - i.e. cable power
line_sd   = what to set to make the UPS shut down the load

Incoming lines:

line_ol   = flag that appears for on line / on battery
val_ol    = value of that flag when the UPS is on battery
line_bl   = flag that appears for low battery / battery OK
val_bl    = value of that flag when the battery is low

This may seem a bit confusing to have two variables per value that
we want to read, but here's how it works.  If you set line_ol to
TIOCM_RNG, then the value of TIOCM_RNG (0x080 on my box) will be anded
with the value of the serial port whenever a poll occurs.  If that flag
exists, then the result of the and will be 0x80.  If it does not exist,
the result will be 0.

So, if line_ol = foo, then val_ol can only be foo or 0.  

As a general case, if line_ol == val_ol, then the value you're reading
is active high.  Otherwise, it's active low.  Check out the guts of
upsdrv_updateinfo() to see how it really works.

Custom definitions
------------------

Late in the 1.3 cycle, a feature was merged which allows you to create
custom monitoring settings without editing the model table.  Just set
upstype to something close, then use settings in ups.conf to adjust the
rest.  See the genericups man page for more details.
