I've got a Powerware 5119 RM UPS.

driver.list says to use "genericups upstype=20", however I know this UPS supports the UPS Code II protocol, so I wanted to use the upscode2 driver. It took some hacking but finally it works.

I'm using NUT 2.4.1 and upscode2 driver version 0.87 (however the latest r2350 version of upscode2.c isn't significantly different, so I think all my results still apply).

Here's the hardware:
Apple G5 Xserve running Mac OS X Server 10.5.8
IOGEAR GUC2322 USB-to-serial adapter (uses Moschip 78XX)
Powerware Model PW5119, P/N 05144717-5501, purchased 12/2000 so maybe old firmware?

Here's what upsc says about this UPS:
ups.mfr: Powerware
ups.model: UPS 1440 VA FW -0039
ups.power.nominal: 1440.00
ups.serial: TS381A0198

Here's what I have in ups.conf:
        driver = upscode2
        port = /dev/tty.MCS78XX_Port0.0
        manufacturer = "Powerware"
        desc = "Powerware 5119 RM on myhostname"
        output_pace = 300
        use_crlf

Setting output_pace to 300 seemed to make communications more robust. YMMV. UPS Code II spec says you need use_crlf, but it seems to work even without it.

The upscode2 driver worked great for normal status, except it failed to power down the UPS. After much debugging I discovered the following problems:

1. The driver successfully sends the UPPC powerdown command, followed by the security string, and then exits. However the UPS ignored the UPPC command and never shut down. By performing a UPTP command right after the UPPC then the UPPC is recognized! Maybe the UPS doesn't like the serial communication being dropped so abruptly?

2. UPS Code II spec says you can view the values of UPSD and UPPC by sending the command string followed by a parameter of "0". However for my UPS this sets the value to 0! In order to view the value you must send "0000". So in upsc_commandlist I changed

  upsc_getvalue(cp->upsc, "0", cp->upsp, cp->cmd, NULL);

to

  upsc_getvalue(cp->upsc, "0000", cp->upsp, cp->cmd, NULL);

and all works correctly.

3. I want to specify a custom shutdown delay value. I can use upsrw

  upsrw -s ups.delay.shutdown=60 -u admin -p password UPSNAME

and the parameter is correctly stored into the UPS using UPSD. And you can read this value back (if you fixed item 2. above). I do this at boot time.

However the driver ignores my setting, and forces UPSD to have a value of "1" just before issuing the UPPC shutdown command. Removing this UPSD allows the custom value to be used correctly.

Also I changed the shutdown messages so the ups.delay.* values are reported.


With all that, here's what upsdrv_shutdown looks like:

void upsdrv_shutdown(void)
{
        if (upsc_commandlist()) {
                if (!can_upsd || !can_uppc) {
                        fatalx(LOG_EMERG, "Shutdown called, but UPS does not support 
it");
                }
        } else {
upslogx(LOG_EMERG, "Can't determine if shutdown is supported, attempting anyway");
        }

        upslogx(LOG_EMERG, "Emergency shutdown");

        char msg[100];
snprintf(msg, 100, "UPS will reboot %ld seconds after shutdown", strtol(dstate_getinfo("ups.delay.reboot"),NULL,10));
        upslogx(LOG_EMERG, msg);
snprintf(msg, 100, "UPS shutting down in %ld seconds...", strtol(dstate_getinfo("ups.delay.shutdown"),NULL,10));
        upslogx(LOG_EMERG, msg);

        upscsend("UPPC");     /* Powercycle UPS */
        upscsend("IJHLDMGCIU"); /* security code */

        /* do something so connection doesn't drop right after UPPC command */
        upsc_getvalue("UPTP", NULL, "NNAME", "ups.model", NULL);
}

I'm sure a real C hacker could find a cleaner/better/elegant way to print the messages, but hey I'm a hardware guy. I'm just happy it's all working.

-seg

_______________________________________________
Nut-upsdev mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/nut-upsdev

Reply via email to