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

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.

To know if this driver will work with your UPS, compare the table below
with the information you have regarding its monitoring capabilities.
If you have an unlisted model that just happens to put the signals in
the same place as a listed model, it might just work.

Abbreviations:
  OB - On battery (Power failure) line (opposite of OL - on line)
  LB - Low battery line
  SD - Shutdown line
  CP - Cable power (must be present for cable to have valid reading)
 CTS - Clear to send signal (from UPS)
 RTS - Ready to send signal (from PC)
 DCD - Data carrier detect (from UPS)
 RNG - Ring indicate (from UPS)
 DTR - Data terminal ready (from PC)
  ST - Send a BREAK on the transmit data line

"num" below is the type number you'd use with "upstype" for this driver.

A - in front of the signal name (like -RNG) means that the indicated
condition is signaled with an active low signal.  -RNG in the LB column
means that the battery is low when that line goes low, and the battery
is OK when that line is held high.

num | Model name/info                          |  OB  |  LB  |  SD  |  CP  |
----+------------------------------------------+------+------+------+------+
 0  | UPSONIC LAN Server 600                   |  CTS |  DCD | -DTR |  DTR |
    |                                          |      |      |  RTS |  RTS |
----+------------------------------------------+------+------+------+------+
 1  | APC Back-UPS with 940-0095A/C cable      |  RNG |  DCD |  RTS |  DTR |
----+------------------------------------------+------+------+------+------+
 2  | APC Back-UPS with 940-0020B cable        |  CTS |  DCD |  DTR |  RTS |
    |                                          |      |      |  RTS |      |
----+------------------------------------------+------+------+------+------+
 3  | PowerTech Comp1000 with DTR cable power  |  CTS |  DCD |  DTR |  DTR |
    |                                          |      |      |  RTS |      |
----+------------------------------------------+------+------+------+------+
 4  | Various models with RUPS cables          | -CTS | -DCD | -RTS |  RTS |
    | (Centralion CL, Belkin Resource, more)   |      |      |      |      |
----+------------------------------------------+------+------+------+------+
 5  | Tripp Lite Internet Office 700 (73-0844) | -CTS | -DCD |  DTR |  DTR |
    |                                          |      |      |  RTS |      |
----+------------------------------------------+------+------+------+------+
 6  | Best Patriot (INT51 cable)               | -CTS | -DCD |  RTS |  DTR |
----+------------------------------------------+------+------+------+------+
 7  | CyberPower Power99                       | -CTS | -DCD |  DTR |  RTS |
----+------------------------------------------+------+------+------+------+
 8  | Nitram Elite UPS                         | -CTS | -DCD | none |  DTR |
----+------------------------------------------+------+------+------+------+
 9  | APC Back-UPS with 940-0023A cable        |  DCD |  CTS |  RTS | none |
----+------------------------------------------+------+------+------+------+
 10 | Victron Lite (crack cable)               | -CTS | -DCD |  DTR |  RTS |
----+------------------------------------------+------+------+------+------+
 11 | Powerware 3115                           |  CTS | -DCD |   ST |  DTR |
----+------------------------------------------+------+------+------+------+
 12 | APC Back-UPS Office with 940-0119A cable |  CTS |  DCD |  DTR |  RTS |
----+------------------------------------------+------+------+------+------+
 13 | RPT Repoteck RPT-800A, RPT-162A          | -DCD | -CTS |   ST |  DTR |
    |                                          |      |      |      |  RTS |
----+------------------------------------------+------+------+------+------+
 14 | Online P-series                          | -DCD | -CTS |  RTS |  DTR |
----+------------------------------------------+------+------+------+------+
 15 | PowerWare 5119 ("NetUPS")                | -CTS | -DCD |   ST |  DTR |
----+------------------------------------------+------+------+------+------+

Similar models
==============

Many UPS companies put out models with similar interfaces.  The RUPS
cable seems to be especially popular in the "power strip" variety of UPS
found in office supply stores.  If your UPS works with an entry in the
table above, but the model or manufacturer information don't match,
don't despair  You can fix that easily with the mfr and model variables.

In ups.conf, the entry might look like this:

	[myups]
		driver = genericups
		port = /dev/ttyS0
		upstype = 4
		mfr = Belkin
		model = Resource

If your UPS isn't listed above
==============================

If none of the existing types match your UPS hardware, you can try going
through the list until you find one that works.  There is a lot of cable
and interface reuse in the UPS world, and you may just find a match.

To do this, first make sure nothing important is plugged into the
outlets on the UPS, as you may inadvertently switch it off.  Definitely
make sure that the computer you're using is not plugged into that UPS.
Plug in something small like a lamp so you know when power is being
supplied to the outlets.

Now, you can either attempt to make an educated guess based on the
documentation your manufacturer has provided (if any), or just start
going down the list.  

Step 1
------

Pick a driver to try from the list (genericups -h) and go to step 2.

Step 2
------

Start the driver with the type you want to try -

	genericups -x upstype=n /dev/port

Let upsd sync up (watch the syslog), and then run upsc to see what it
found.  If the STATUS is right (should be OL for on line), go to step 3,
otherwise go back to step 1.

Step 3
------

Disconnect the UPS from the wall/mains power.  This is easiest if you
have a switched outlet in between it and the wall, but you can also just
pull the plug to test.  The lamp should stay lit, and the status should
switch to "OB".  If the lamp went out or the status didn't go to "OB"
within about 15 seconds, go to step 1.  Otherwise, continue to step 4.

Step 4
------

At this point, we know that OL and OB work.  If nothing else beyond
this point works, you at least know what your OL/OB value should be.

Wait for the UPS to start complaining about a low battery.  Depending on
the size of your UPS battery and the lamp's bulb, this could take
awhile.  It should start complaining audibly at some point.  When this
happens, STATUS should show "OB LB" within 15 seconds.  If not, go to
step 1, otherwise continue to step 5.

Step 5
------

So far: OL works, OB works, and LB works.

With the UPS running on battery, run the genericups driver with the -k
switch to shut it down.

	genericups -x upstype=n -k /dev/port

If the UPS turns off the lamp, you're done.  At this point, you have
verified that the shutdown sequence actually does what you want.  You
can start using the genericups driver with this type number for normal
operations.

You should use your findings to add a section to your ups.conf.
Here is a quick example:

	[myups]
		driver = genericups
		port = /dev/ttyS0
		upstype = 1

Change the port and upstype values to match your system.

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

Try the above testing sequence first.  If that doesn't work, you can
try contacting the mailing list with information about the serial port
on your UPS.  Unless it's truly bizarre, a solution should be found
rather quickly.  There are only so many combinations that you can make
with 4 incoming and 2 outgoing lines.  

For those of you keeping track, those are the 6 "high/low" lines on
your standard 9 pin serial port.  The other 3 are TxD, RxD, and GND.  If
you try to run a high/low signal on any of those, the results will be
unpredictable.  Any UPS hooked to the transmit or receive lines on the
PC is likely a "smart" variant and needs a special driver.  Consult a
guru.

Another possibility is that the UPS relies on a special cable to route
the signals to their destination rather than using a standard
straight-through configuration.  Be aware that some manufacturers
(hi APC) put electronics in their cables to do magic things depending
on whether they are plugged in or not, so measuring it with a meter may
give strange readings.

The mailing lists are archived at http://lists.exploits.org/ - try
searching there before posting a request.  Someone may be working on the
same problem already.  By the way, 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.

Model-specific notes
====================

Centralion CL Series
--------------------

Neil Muller wrote in with the Centralion CL Series support information,
and provided some details on how the shutdown works.  Specifically, if
the driver starts up while the UPS is on battery power, the short
interval with the default line settings will power down the load.

Tripp Lite Internet Office 700
------------------------------

Stephen Brown provided the specs for this model's support.  He notes
that you must use the black 73-0844 cable instead of the gray 73-0743
cable.  This code should work with any of their models that uses the Lan
2.2 interface - look for the sticker by the DB9 connector on the UPS.

TrippLite Lan 2.1 interface
---------------------------

Q Giese reports that type 5 will work with the 73-0724 cable.
This was tested with the OmniSmart 675 PNP on Red Hat 7.2.

PhoenixTec A1000
----------------

Types 7 and 10 have been reported to work with this hardware.
