Making the BNT-600 UPS work with NUT

I’ve had my blacknight 600VA UPS for a while now, and was well aware of the fact that NUT makes use of the powercom driver to interface with it. I also knew that it was supposed to be able to do things like auto-shutdown and restore power on resume (unlike some of the considerably smarter UPSes it won’t wait until battery restored to a certain point). Well, I finally made it work the way I want it…

The way it should (imho) be:

Firstly, whenever power fails for longer than one minute, I want it to go down. If the UPS reaches battery low – it must go down. When it goes down, I want it to stay down until power is restored, at which point it should power back up automatically. This seems rather simple, but many of the lower end UPSes seems to simply be incapable of this.

NUT:

NUT is reasonably well described on it’s site, yet I’m still going to give a very quick overview ignoring all the network infrastructure stuff, essentially NUT consists of three components:

  1. upsdrv – This is the local low-level drivers that interfaces with the UPS. You need this if you need an agent on the machine that communicates with the UPS over a serial port.
  2. upsd – A daemon that communicates with the upsdrv or snmpd (Yes, some UPSes communicates directly with the network) instances and provides status information to upsmon
  3. upsmon – A daemon that controls policy. It can communicate with remote upsd instances for multi-power grids etc …

There is also upssched but that is in fact a separate program that happens to interface with NUT to schedule UPS commands (well, it can probably be abused for other things too, but it was designed to work with NUT).

In my case I really don’t care about all the extra network features, I just have a single upsdrv running with a upsd exposing that to a local upsmon that makes use of upssched to shut down the machine 60 seconds after a power failure (permitting power doesn’t get restored).

The basic driver:

The Blacknight 600VA masquerades as a BNT-600 UPS from Powercom. Thus we bring it up with the powercom driver using a section in /etc/nut/ups.conf as follows:

[bnt600]
driver = powercom
port = /dev/ttyS0
type = KIN1500AP
shutdownArguments={{0,5},y}
modelname = “600VA Black Knight”
desc = “PowerCom: 600VA Black Knight”

Nothing complicated. The bit that took the longest to figure out was the shutdownArguments. Long story, but the whole system would shut down, without powering down, hit reset, as soon as upsdrv came up the beeping would start and after a little over 10 minutes (intiially I used the default {{0,10},y}) the system would simply cut out. In the above configuration the UPS stays up for 5 seconds from when “cut power” is issued until it goes down.

You need to vary the port based on what you’re connecting with, I’ve only got one serial port and it happens to be /dev/ttyS0. upsdrv will automatically set the correct parameters.

upsd:

This was probably the easiest of everything. We need a daemon, and we need a user. upsd.conf has the following 4 (default) lines:

ACL all 0.0.0.0/0
ACL localhost 127.0.0.1/32

ACCEPT localhost
REJECT all

And upsd.users I basically uncommented the user:

[monuser]
password = pass
allowfrom = localhost
upsmon master

And that’s it. Fire it up and you should be able to issue “upsc bnt600@localhost” and get some stats for your effort. Unplugging and plugging the AC, and fooling around should get you updates to ups.status and some of the other values will vary as well.

upsmon:

The config file itself serves as very good documentation, however, I’m still going to run through all my options:

RUN_AS_USER nut

Gentoo installs the system with a user called nut, and all the important (/var/lib/nut) locations is owned by this user, so run upsmon as that user.

MONITOR bnt600@localhost 1 monuser pass master

Indicates which UPS to monitor. This needs to match your ups name and monitoring user.

MINSUPPLIES 1

Indication of how many power inputs needs to be not in BATTLOW status. A value of 1 is probably a good one since most desktops only have one AC inlet in any case.

SHUTDOWNCMD “/sbin/shutdown -h +0”

Command that will be executed to bring the system to it’s knees.

NOTIFYCMD /usr/sbin/upssched

We want to be able to schedule shutdowns based on when power is lost, and upssched performs this task very well indeed, so we use it as our NOTIFYCMD for the EXEC notifications below.

POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15

All kinds of synchronization options, these values are the defaults and seems to work pretty well.

POWERDOWNFLAG /etc/killpower

This needs to match with what your halt.sh script uses to check whether to kill the UPS or powerdown the motherboard.

NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL
NOTIFYFLAG FSD SYSLOG+WALL
NOTIFYFLAG COMMOK SYSLOG+WALL
NOTIFYFLAG COMMBAD SYSLOG+WALL
NOTIFYFLAG SHUTDOWN SYSLOG+WALL
NOTIFYFLAG REPLBATT SYSLOG+WALL
NOTIFYFLAG NOCOMM SYSLOG+WALL
NOTIFYFLAG NOPARENT SYSLOG+WAL

The notifcation flags. I’m not sure what the defaults are but SYSLOG+WALL is what the commented options are for all options, I want to schedule events when we go ONBATT and cancel when we go back ONLINE, thus I explicitly added EXEC here (this will cause upssched to be executed whenever AC input changes status).

RBWARNTIME 43200
NOCOMMWARNTIME 300

How often NUT should warn us if we need to replace a battery, or if there is comms failures to the UPS.

FINALDELAY 5

How long to wait after deciding that a shutdown is required and actually initiating the shutdown. 5 seconds seems fair.

upsshed:

upssched’s sole purpose is to rig a time-based delayed shutdown. It executes another script, so I created a simple script called ups_trigger_shutdown in /usr/local/sbin/ with the following content:

#! /bin/bash
/usr/sbin/upsmon -c fsd

This basically issues a command to upsmon to initiate an emergency shutdown as if all power is exhausted. Whenever this script is executed as either the root or nut user the system will shut down. You should probably test this and make sure that this is the case. Make sure that you don’t have any unsaved work.

The /etc/nut/upssched.conf file is pretty simple all things considered, and all options are discussed here:

CMDSCRIPT /usr/local/sbin/ups_trigger_shutdown

The script to execute. Point this to the above file. This command will be executed whenever the system has been without power for 60 seconds.

PIPEFN /var/lib/nut/upssched.pipe
LOCKFN /var/lib/nut/upssched.lock

Files used for IPC purposes. The default is another subdirectory under /var/lib/nut – I was too lazy to create that folder and fix the perms so I just updated these options instead. It’s arguable whether that is in fact less effort.

Now for the magic, there is two cases where we want to take action. ONBATT we want to start a timer, and at ONLINE we want to cancel that timer:

AT ONBATT * START-TIMER upsgone 60
AT ONLINE * CANCEL-TIMER upsgone

And now, after making sure that upsdrv, upsd and upsmon is started you should be able to tail your system log, and when you unplug the AC feed to the UPS you should see a timer being scheduled. Restoring AC should stop the timer, now unplug it and leave it for 60 seconds, it should initiate a shutdown. Once powered down the beeping on your UPS should change and 5 seconds later the power should cut out. If you now restore AC to the UPS it will automatically power back up and if your BIOS is configured in such a way so will your PC.

The UPS also does the right thing should power have been restored after initiating a shutdown but before we ask the UPS to cut the load, it will actually cut the load, and then immediately restore AC to your PC, resulting in the BIOS actually thinking that the power did go off and kicking in with the status on AC restore action (usually restore to previous power state, eg, if the PC was on before the power failure it will go back on, and if the PC was off it will stay off).

Why bother with writing this?

Because it took me longer than I care to admin to make this work, and I’m pretty sure there is others out there that would like the assistance. Not to mention that information is rather scarce on the specific UPS model.

One Response to “Making the BNT-600 UPS work with NUT”

  1. Jaco Kroon says:

    Please note that this is no longer valid. The drivers changed and nothing I do currently gets me sane answers.

    It seems BNT-other above instead of KIN1500A does the trick, however, I’m getting a charge value of zero on my test UPS which makes me wonder somewhat.