ifdef::website[]
Project history
===============
endif::website[]

This page is an attempt to document how everything came together.

The Network UPS Tools team would like to warmly thank Russell Kroll.

Russell initially started this project, maintaining and improving it for
over 8 years (1996 -- mid 2005).

Prototypes and experiments
--------------------------

May 1996: early status hacks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

APC's Powerchute was running on kadets.d20.co.edu (a BSD/OS box) with
SCO binary emulation. Early test versions ran in cron, pulled status
from the log files and wrote them to a .plan file. You could see the
results by fingering `pwrchute@kadets.d20.co.edu` while it lasted:

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

    Last login Sat May 11 21:33 (MDT) on ttyp0 from intrepid.rmi.net
    Plan:
    Welcome to the UPS monitor service at kadets.d20.co.edu.
    The Smart-UPS attached to kadets generated a report at 14:24:01 on 05/17/96.
    During the measured period, the following data points were taken:
    Voltage ranged from 115.0 VAC to 116.3 VAC.
    The UPS generated 116.3 VAC at 60.00 Hz.
    The battery level was at 27.60 volts.
    The load placed on the UPS was 024.9 percent.
    UPS temperature was measured at 045.0 degrees Celsius.
    Measurements are taken every 10 minutes by the upsd daemon.
    This report is generated by a script written by Russell Kroll<rkroll@kadets>.
    Modified for compatibility with the BSD/OS cron daemon by Neil Schroeder

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

This same status data could also be seen with a web browser, since we
had rigged up a CGI wrapper script which called finger.


January 1997: initial protocol tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Initial tests with a freestanding non-daemon program provided a few
basic status registers from the UPS. The 940-0024C cable was not yet
understood, so this happened over the [attachment:apcevilhack.jpg evil
two-wire serial hack].

------------------------------------------------------------------------
    Communicating with SMART-UPS 700 S/N WS9643050926 [10/17/96]
    Input voltage range: 117.6 VAC - 118.9 VAC
    Load is 010.9% of capacity, battery is charged to 100.0% of capacity
------------------------------------------------------------------------

Note that today's apcsmart driver still displays the serial number when
it starts, since it is derived from this original code.

September 1997: first client/server code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The first split daemon/client code was written. upsd spoke directly to
the UPS (APC Smart models only) and communicated with upsc by sending
binary structures in UDP datagrams.

The first CGI interface existed, but it was all implemented with shell
scripts. The main script would call upsc to retrieve status values. Then
it would cat a template file through sed to plug them into the page.

image::images/old-cgi.png[Old CGI screenshot]

upsstats actually has since returned to using templates, despite having
a period in the middle when it used hardcoded HTML.

The images were also created with shell scripts. Each script would call
upsc to get the right value (utility, upsload, battcap). It then took
the value, plugged it into a command file with sed, and passed that into
'fly', a program which used an interpreted language to create images.
fly actually uses gd, just like upsimage does today.

This code later evolved into Smart UPS Tools 0.10.

Smart UPS Tools
---------------

March 1998: first public release
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Version 0.10 was released on March 10, 1998. It used the same design as
the pre-release prototype. This made expansion difficult as the binary
structure used for network communications would break any time a new
variable was added. Due to byte-ordering and struct alignment issues,
the code usually couldn't talk over the network to a system with a
different architecture. It was also hopelessly bound to one type of UPS
hardware.

Five more releases followed with this design followed. The last was
0.34, released October 27, 1998.

June 1999: Redesigned, rewritten
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Following a long period of inactivity and two months of prerelease
testing versions, 0.40.0 was released on June 5, 1999. It featured a
complete redesign and rewrite of all of the code. The layering was now
in three pieces, with the single driver (smartups) separate from the
server (upsd).

Clients remained separate as before and still used UDP to talk to the
server, but they now used a text-based protocol instead of the brittle
binary structs. A typical request like "REQ UTILITY" would be answered
with "ANS UTILITY 120.0".

The ups-trust425-625 driver appeared shortly after the release of
0.40.0, marking the first expansion beyond APC hardware.

Over the months that followed, the backupspro driver would be forked
from the smartups driver to handle the APC Back-UPS Pro line. Then the
backups driver was written to handle the APC Back-UPS contact-closure
models. These drivers would later be renamed and recombined, with
smartups and backupspro becoming apcsmart, and backups became genericups.

The drivers stored status data in an array. At first, they passed this data to
upsd by saving it to a file. upsd would reread this file every few seconds to
keep a copy for itself. This was later expanded to allow shared memory mode,
where only a stub would remain on the disk. The drivers and server then passed
data through the shared memory space.

upsd picked up the ability to monitor multiple drivers on the system, and the
"upsname@hostname" scheme was born. Access controls were added, and then the
network code was expanded to allow TCP communications, which at this point were
on port 3305.


Network UPS Tools
-----------------

September 1999: new name, new URL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Several visitors to the web page and subscribers to the mailing lists provided
suggestions to rename the project. The old name no longer accurately described
it, and it was perilously close to APC's "Smart-UPS" trademark. Rather than
risk problems in the future, the name was changed. Kern Sibbald provided the
winner: Network UPS Tools, which captures the essence of the project and makes
for great short tarball filenames: nut-x.y.z.tar.gz.

The new name was first applied to 0.42.0, released October 31, 1999.
This is also when the web pages moved from the old
`http://www.exploits.org/~rkroll/smartupstools/` URL to the replacement
at `http://www.exploits.org/nut/` to coincide with the name change.

More drivers were written and the hardware support continued to grow. upsmon
picked up the concepts of what is now known as "primary" and "secondary",
and could now handle environments where multiple systems get power from a
single UPS.

Manager mode was added to allow changing the value of read/write variables
in certain UPS models.

June 2001: common driver core
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Up to this point, all of the drivers compiled into freestanding programs, each
providing their own implementation of main(). This meant they all had to check
the incoming arguments and act uniformly. Unfortunately, not all of the
programs behaved the same way, and it was hard to document and use consistently.
It also meant that startup scripts had to be edited depending on what kind of
hardware was attached.

Starting in 0.45.0, released June 11, 2001, there was a new common core for
all drivers called `main.c`. It provided the main function and called back to
the `upsdrv_*` functions provided by the hardware-specific part of the drivers.
This allowed driver authors to focus on the UPS hardware without worrying about
the housekeeping stuff that needs to happen.

This new design provided an obvious way to configure drivers from one file, and
so `ups.conf` was born. This eventually spawned upsdrvctl, and now all drivers
based on this common core could be started or stopped with one command. Startup
scripts now could contain "upsdrvctl start", and it didn't matter what kind of
hardware or how many UPSes you had on one system.

Interestingly, at the end of this month, Arnaud Quette entered the UPS world,
as a subcontractor of the now defunct MGE UPS SYSTEMS. This marked the start of
a future successful collaboration.

May 2002: casting off old drivers, IANA port, towards 1.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

During the 0.45.x series, both the old standalone drivers and the ones which
had been converted to the common core were released together. Before the
release of 0.50.0 on May 24, 2002, all of the old drivers were removed.
While this shrank the list of supported hardware, it set the precedent for
removing code which isn't receiving regular maintenance. The assumption is
that the code will be brought back up to date by someone if they actually
need it. Otherwise, it's just dead weight in the tree.

This change meant that all remaining drivers could be controlled with the
`upsdrvctl` and `ups.conf`, allowing the documentation to be greatly
simplified. There was no longer any reason to say "do this, unless you
have this driver, then do this".

IANA granted an official port number to the project, and the network code
switched to port 3493. It had previously been on 3305 which is assigned to
`odette-ftp`. 3305 was probably picked in 1997 because it was the fifth
project to spawn from some common UDP server code.

After 0.50.1, the 0.99 tree was created to provide a tree which would receive
nothing but bug fixes in preparation for the release of 1.0. As it turned out,
very few things required fixing, and there were only three releases in this
tree.

Leaving 0.x territory
---------------------

August 2002: first stable tree: NUT 1.0.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

After nearly 5 years of having a 0.x version number, 1.0.0 was released on
August 19, 2002. This milestone meant that all of the base features that
you would expect to find were intact: good hardware support, a network
server with security controls, and system shutdowns that worked.

The design was showing signs of wear from the rapid expansion, but this was
intentionally ignored for the moment. The focus was on getting a good version
out that would provide a reasonable base while the design issues could be
addressed in the future, and I'm confident that we succeeded.

November 2002: second stable tree: NUT 1.2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

One day after the release of 1.0.0, 1.1.0 started the new development tree.
During that development cycle, the CGI programs were rewritten to use template
files instead of hard-coded HTML, thus bringing back the flexibility of the
original unreleased prototype from 5 years before. The `multimon` was removed
from the tree, as the new `upsstats` could do both jobs by loading different
templates.

A new client library called upsclient was created, and it replaced upsfetch.
This new library only supported TCP connections, and used an opaque context
struct to keep state for each connection. As a result, client programs could
now do things that used multiple connections without any conflicts. This was
done primarily to allow OpenSSL support, but there were other benefits from
the redesign.

upsd and the clients could now use OpenSSL for basic authentication and
encryption, but this was not included by default. This was provided as
a bonus feature for those users who cared to read about it and enable
the option, as the initial setup was complex.

After the 1.1 tree was frozen and deemed complete, it became the second
stable tree with the release of 1.2.0 on November 5, 2002.

April 2003: new naming scheme, better driver glue, and an overhauled protocol
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Following an extended period with no development tree, 1.3.0 got things
moving again on April 13, 2003. The focus of this tree was to rewrite
the driver-server communication layer and replace the static naming
scheme for variables and commands.

Up to this point, all variables had names like STATUS, UTILITY, and OUTVOLT.
They had been created as drivers were added to the tree, and there was little
consistency. For example, it probably should have been INVOLT and OUTVOLT,
but there was no OUTVOLT originally, so UTILITY was all we had. This same
pattern repeated with ACFREQ -- is it incoming or outgoing? -- and many more.

To solve this problem, all variables and commands were renamed to a
hierarchical scheme that had obvious grouping. STATUS became ups.status.
UTILITY turned into input.voltage, and OUTVOLT is output.voltage.
ACFREQ is input.frequency, and the new output.frequency is also now
supported. Every other variable or command was renamed in this fashion.

These variables had been shared between the drivers and upsd as values.
That is, for each name like STATUS, there was a #define somewhere in the
tree with an INFO_ prefix that gave it a number. INFO_STATUS was 0x0006,
INFO_UTILITY was 0x0004, and so on, with each name having a matching number.
This number was stored in an int within a structure which was part of the
array that was either written to disk or shared memory.

That structure had several restrictions on expansion and was dropped as the
data sharing method between the drivers and the server. It was replaced by
a new system of text-based messages over Unix domain sockets. Drivers now
accepted a short list of commands from upsd, and would push out updates
asynchronously. upsd no longer had to poll the state files or shared memory.
It could just select all of the driver and client fds and act on events.

At the same time, the network protocol on port 3493 was overhauled to take
advantage of the new naming scheme. The existing "REQ STATUS@su700",
"ANS STATUS@su700 OL" scheme was showing signs of age, and it really
only supported the UPS name (@su700) as an afterthought. The new protocol
would now use commands like GET and LIST, leading to exchanges like
"GET VAR su700 ups.status" and "VAR su700 ups.status OL". These responses
contain enough data to stand alone, so clients can now handle them
asynchronously.

July 2003: third stable tree: NUT 1.4.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On July 25, 2003, 1.4.0 was released. It contained support for both the
old "REQ" style protocol (with names like STATUS), and the new "GET" style
protocol (with names like ups.status). This tree is provided to bridge the
gap between all of the old releases and the upcoming 2.0.

2.0 will be released without support for the old REQ/STATUS protocol.
The hope is that client authors and those who have implemented their own
monitoring software will use the 1.4 cycle to change to the new protocol.
The 1.4 releases contain a lot of compatibility code to make sure both
work at the same time.

July 2003: pushing towards 2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1.5.0 forked from 1.4.0 and was released on July 29, 2003. The first changes
were to throw out anything which was providing compatibility with the older
versions of the software. This means that 1.5 and the eventual 2.0 will not
talk to anything older than 1.4.

This tree continues to evolve with new serial routines for the drivers which
are intended to replace the aging upscommon code which dates back to the early
0.x releases. The original routines would call alarm and read in a tight loop
while fetching characters. The new functions are much cleaner, and wait for
data with select. This makes for much cleaner code and easier strace/ktrace
logs, since the number of syscalls has been greatly reduced.

There has also been a push to make sure the data from the UPS is well-formed
and is actually usable before sending updates out to upsd. This started
during 1.3 as drivers were adapted to use the dstate functions and the
new variable/command names. Some drivers which were not converted to the
new naming scheme or didn't do sanity checks on the incoming UPS data from
the serial port were dropped from the tree.

This tree was released as 2.0.0.

Backwards and Forwards Compatibility (NUT v1.x vs. v2.x)
--------------------------------------------------------

The old network code spans a range from about 0.41.1 when TCP support
was introduced up to the recent 1.4 series.  It used variable names
like STATUS, UTILITY, and LOADPCT.  Many of these names go back to the
earliest prototypes of this software from 1997.  At that point there
was no way to know that so many drivers would come along and introduce
so many new variables and commands.  The resulting mess grew out of
control over the years.

During the 1.3 development cycle, all variables and instant commands
were renamed to fit into a tree-like structure.  There are major groups,
like input, output and battery.  Members of those groups have been
arranged to make sense - input.voltage and output.voltage compliment
each other.  The old names were UTILITY and OUTVOLT.  The benefits in
this change are obvious.

The 1.4 clients can talk to either type of server, and can handle either
naming scheme.  1.4 servers have a compatibility mode where they can
answer queries for both names, even though the drivers are internally
using the new format.

When 1.4 clients talk to 1.4 or 2.0 (or more recent) servers, they will
use the new names.

Here's a table to make it easier to visualize:

[options="header"]
|=============================================
|                   4+| Server version
| *Client version*    | 1.0 | 1.2 | 1.4 | 2.0+
| 1.0                 | yes | yes | yes | no
| 1.2                 | yes | yes | yes | no
| 1.4                 | yes | yes | yes | yes
| 2.0+                | no  | no  | yes | yes
|=============================================

Version 2.0, and more recent, do not contain backwards compatibility for
the old protocol and variable/command names.  As a result, 2.0 clients can't
talk to anything older than a 1.4 server.  If you ask a 2.0 client to
fetch "STATUS", it will fail.  You'll have to ask for "ups.status"
instead.

Authors of separate monitoring programs should have used the 1.4 series
to write support for the new variables and command names.  Client
software can easily support both versions as long as they like.  If upsd
returns 'ERR UNKNOWN-COMMAND' to a GET request, you need to use REQ.

networkupstools.org
-------------------

November 2003: a new URL
~~~~~~~~~~~~~~~~~~~~~~~~

The bandwidth demands of a project like this have slowly been forcing me to
offload certain parts to other servers. The download links have pointed
offsite for many months, and other large things like certain UPS protocols
have followed. As the traffic grows, it's clear that having the project
attached to exploits.org is not going to work.

The solution was to register a new domain and set up mirrors. There are two
initial web servers, with more on the way. The main project URL has changed
from `http://www.exploits.org/nut/` to https://www.networkupstools.org.
The actual content is hosted on various mirrors which are updated regularly
with rsync, so the days of dribbling bits through my DSL should be over.

This is also when all of the web pages were redesigned to have a simpler
look with fewer links on the left side. The old web pages used to have 30
or more links on the top page, and most of them vanished when you dropped
down one level. The links are now constant on the entire site, and the old
links now live in their own groups in separate directories.

Second major version
--------------------

March 2004: NUT 2.0.0
~~~~~~~~~~~~~~~~~~~~~

NUT 2.0.0 arrived on March 23, 2004. The jump to version 2 shows the difference
in the protocols and naming that happened during the 1.3 and 1.5 development
series. 2.0 no longer ships with backwards compatibility code, so it's smaller
and cleaner than 1.4.


The change of leadership
------------------------

February 2005: NUT 2.0.1
~~~~~~~~~~~~~~~~~~~~~~~~

The year 2004 was marked by a release slowdown, since Russell was busy with
personal subjects. But the patches queue was still growing quickly.

At that time, the development process was still centralized. There was no
revision control system (like the current Subversion repository), nor trackers
to interact with NUT development.
Russell was receiving all the patches and requests, and doing all the work on
his own, including releases.

Russell was more and more thinking about giving the project leadership to
Arnaud Quette, which finally happened with the 2.0.1 release in February 2005.

This marked a new era for NUT...

First, Arnaud aimed at opening up the development by creating a project on the
http://www.debian.org/[Debian]
http://alioth.debian.org/projects/nut/[Alioth Forge].
This allowed to build the team of hackers that Russell dreamed about.
It also allows to ensure NUT's continuation, whatever happens to
the leader. And that would most of all boost the projects contributions.


////////////////////////////////////////////////////////////////////////
*sandbox*

TO BE COMPLETED + ADD A LINK TO IDEA / FUTURE

link on the team + history

mention:
- MGE supporting officially,
- USB / SNMP / XML drivers (first non serial drivers),
- Power Management (HAL) bridging,
- PDU support,
- perl / python support...
- client history and evolution (wmnut: 01/01/2002)

release history
<LI>July 7, 2008: Client activity: new client <A HREF="http://www.lestat.st/informatique/projets/nut-monitor-en">NUT-Monitor</A>
<LI>June 27, 2008: Client activity: new Python class <A HREF="http://www.lestat.st/informatique/projets/pynut-en">PyNUT</A>
<LI>June 19, 2008: Client activity: <A HREF="http://www.knut.noveradsl.cz/knutclient/">KNutClient 0.9.4</A>
<LI>May 7, 2008: 2.2.2 released
<LI>December 21, 2007: 2.2.1 released
<LI>August 31, 2007: Client activity: <A HREF="http://rudd-o.com/projects/ups-monitor/">UPS Monitor</A> link update
<LI>August 31, 2007: Client activity: <A HREF="http://sourceforge.net/projects/winnutclient/">Windows NUT client 1.5.0</A>
<LI>July 5, 2007: 2.2.0 released
<LI>June 5, 2007: Client activity: <A HREF="http://collectd.org/">collectd NUT plugin</A>
<LI>April 10, 2007: Client activity: <A HREF="http://www.knut.noveradsl.cz/knutclient/">KNutClient 0.9.3</A>
<LI>January 15, 2007: 2.0.5 released
<LI>January 8, 2007: Client activity: <A HREF="http://sourceforge.net/projects/winnutclient/">Windows NUT client</A>
<!-- LI>July 27, 2006: 2.0.4 released
<LI>February 7, 2006: 2.0.3 released
<LI>June 27, 2005: 2.0.2 released
<LI>June 15, 2005: new <A HREF="lists/index.html">mailing lists</A> ready on <A HREF="http://alioth.debian.org/mail/?group_id=30602">Alioth</A>
<LI>April 15, 2005: new development infrastructure ready on <A HREF="http://alioth.debian.org/projects/nut/">Alioth</A>
<LI>March 15, 2005: Client activity: first beta of MGE <A HREF="http://www.mgeups.com/products/pdt230/software/sp97/solpaclinux.htm">Personal Solution Pac</A>
<LI>March 11, 2005: Client activity: <A HREF="http://www.amautacorp.com/staff/Rudd-O/projects/pages/ups-front">UPS Monitor</A> 0.8 released
<LI>February 24, 2005: 2.0.1 released

Note: use the NEWS file!

////////////////////////////////////////////////////////////////////////
