Desc: Using the generic UPS driver
File: generic-ups.txt
Date: 6 October 2002
Auth: Russell Kroll <rkroll@exploits.org>

Conversion notice
=================

The information in this file is moving to the genericups(8) man page.

There are still some elements in this file about adding new types that
has not been moved yet, though.

If you need to add a new type to genericups.h, scroll down a bit.

--------------------------------------------------------------------------

If you have a UPS that does "contact closure" reporting, you probably
need to use this driver.  For APC Back-UPS models, this is the only
method of monitoring that's available.  This is also used on other APC
units when only their grey "dumb" cables are available.

The basic idea is for the UPS to send high/low signals back to the
serial port's various lines to indicate status.  These signals usually
are the following:

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

What's more, there is usually an outgoing signal from the PC that is
used to shut down the load side of the UPS.  This is necessary to ensure
that all connected systems are reset, even if it means powering them
off.  Otherwise, a system may halt and remain halted as power returns at
the worst possible time.

Adding new support
==================

Try the testing sequence in the genericups man page first.  If that
doesn't work, you'll probably need to create a new entry for your UPS.

Be sure to get as much information as possible about the serial port on
your hardware.  You'll need to know which pins get the different status
signals, and whether they are active high or active low.  Some UPS
hardware/cabling also requires power from the PC to work, so check for
that as well.

There are only four incoming and two outgoing lines, so there aren't too
many combinations left that haven't already been covered by this driver.
The other lines on the standard 9 pin serial port are transmit, receive,
and the ground.  Trying to do a high/low signal on any of those will
give unpredictable results.

Any UPS on the transmit/receive lines is either a "smart" variant or is
doing something very peculiar for status testing.  With the exception of
hardware that uses a BREAK from the PC, anything on those lines will not
work with this driver.  Consult a guru.

Some manufacturers do magic things in their cables to route the signals
around.  This means that straight-through cabling will not work.  Others
(hi APC) also put electronics in the cables to do even more strange
things depending on the status of the PC.  This can affect meter
readings, so keep that in mind when testing your cables.

You should also search the mailing list archives to see if someone else
is working on the same hardware:

	http://lists.exploits.org/

You can get on the mailing list by sending "subscribe ups" to
majordomo@lists.exploits.org.

Adding new support - hack time
==============================

If you're the brave type that likes hacking code, then it is possible  
to add support for your favorite UPS by adding a new entry.  The most
important part is to figure out which line does what relative to the
PC's serial port.  Then, edit upstab[] in genericups.h and add a new
grouping of information for that model.  Just insert it *before* the
one with all NULLs.

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
updateinfo() to see how it really works.
