Hi,

Got this mail.

It looks like he has a ups with revision before K, and need another
startup. The 'PW_SET_REQ_ONLY_MODE' is not implemented,
so to make it work we have to follow the protocol and send
a 'PW_ID_BLOCK_REQ'. This in comsetup of bcmxcp_ser.c

Also the standard id block ends with 'Statistics Map', so we have to
Skip after reading the length of the 'Size of the Alarm History Block'
in bcmxcp.c ( se my replay). 


Kjell
--- Begin Message ---
I have an older Powerware 9315 UPS that I monitor from a Linux box
running Network UPS Tools and the bcmxcp driver.  I upgraded that
server, including a much newer version of NUT (2.4.3), and now it can't
monitor my UPS.  You are listed as the current author for that driver,
and since I haven't been able to subscribe to the mailing list so far
(I'm not getting the confirmation emails), I thought I'd try a direct
email to you.

I have tracked down much of my problem to the newer driver trying to use
configuration that my UPS doesn't support, such as the command list,
outlet monitoring, and alarm blocks from the ID response.  The XCP PDF
on the NUT website says under "Exceptions" (page 31):

   Unimplemented features may truncate this block; implementations
   before BCM Rev AE did not include the fields after the Statistics
   map.

Mine stops after the Statistics map; I've added code to detect this and
not attempt to decode/use this info (this may be the real cause of the
PW5115 "bug" noted in bcmxcp.c; I was getting an outlet block length of
127 and crazier values for the others).

I'm still having communications problems that I didn't have before;
sometimes bcmxcp is unable to initialize communication with the UPS, and
sometimes it connects and goes stale within a minute (the old setup
never had that problem).  Once it goes stale, it never recovers.

I added explicitly requesting the ID info to the bcmxcp_ser.c init if it
doesn't get a response to the "request only" command, and that seems to
help get it connected at startup most of the time, but it still loses
communication within a minute or two.

Also, once it goes stale, I have to wait at least a bit (a minute or
two?) before it will talk again.  If I immediately restart bcmxcp, it
never establishes communications.

This is a physically different server than before; the old one connected
via a USB-to-serial adapter (standard old PL2303), while the new one is
connected through a PCI-E serial card (I know the card is working okay
because an APC UPS is connected to the other port and is working fine).

Any ideas/suggestions?

I'm including my current patch below; in addition to the above notes, I
added printing the requested command to the error message for no
response (so I could see what was failing).
-- 
Chris Adams <[email protected]>
Systems and Network Administrator - HiWAAY Internet Services
I don't speak for anybody but myself - that's enough trouble.


diff -ur nut-2.4.3-dist/drivers/bcmxcp.c nut-2.4.3/drivers/bcmxcp.c
--- nut-2.4.3-dist/drivers/bcmxcp.c     2011-01-14 13:31:13.228879546 -0600
+++ nut-2.4.3/drivers/bcmxcp.c  2011-01-14 13:42:18.852880304 -0600
@@ -1176,17 +1176,20 @@
        iIndex += 1;
 
        /* Size of command list block */
-       cmd_list_len = get_word(answer+iIndex);
+       if (iIndex < res)
+               cmd_list_len = get_word(answer+iIndex);
        upsdebugx(2, "Length of command list: %d\n", cmd_list_len);
        iIndex += 2;
 
        /* Size of outlet monitoring block */
-       outlet_block_len = get_word(answer+iIndex);
+       if (iIndex < res)
+               outlet_block_len = get_word(answer+iIndex);
        upsdebugx(2, "Length of outlet_block: %d\n", outlet_block_len);
        iIndex += 2;
 
        /* Size of the alarm block */
-       alarm_block_len = get_word(answer+iIndex);
+       if (iIndex < res)
+               alarm_block_len = get_word(answer+iIndex);
        upsdebugx(2, "Length of alarm_block: %d\n", alarm_block_len);
        /* End of UPS ID block request */
 
@@ -1209,7 +1212,8 @@
        init_limit();
 
        /* Get information on UPS commands */
-       init_command_map();
+       if (cmd_list_len)
+               init_command_map();
 
        /* FIXME: leave up to init_command_map() to add instant commands? */
        dstate_addcmd("shutdown.return");
diff -ur nut-2.4.3-dist/drivers/bcmxcp_ser.c nut-2.4.3/drivers/bcmxcp_ser.c
--- nut-2.4.3-dist/drivers/bcmxcp_ser.c 2010-02-11 15:43:23.000000000 -0600
+++ nut-2.4.3/drivers/bcmxcp_ser.c      2011-01-14 13:28:21.282015759 -0600
@@ -47,8 +47,10 @@
 
        while (retry++ < PW_MAX_TRY) {
 
-               if (retry == PW_MAX_TRY)
+               if (retry == PW_MAX_TRY) {
                        ser_send_char(upsfd, 0x1d);     /* last retry is 
preceded by a ESC.*/
+                       usleep(250000);
+               }
 
                sent = ser_send_buf(upsfd, sbuf, command_length);
 
@@ -82,7 +84,7 @@
                        res = ser_get_char(upsfd, my_buf, 1, 0);
 
                        if (res != 1) {
-                               upsdebugx(1,"Receive error 
(PW_COMMAND_START_BYTE): %d!!!\n", res);
+                               upsdebugx(1,"Receive error 
(PW_COMMAND_START_BYTE): %d, cmd=%x!!!\n", res, command);
                                return -1;
                        }
 
@@ -250,6 +252,7 @@
 void pw_comm_setup(const char *port)
 {
        unsigned char   command = PW_SET_REQ_ONLY_MODE;
+       unsigned char   id_command = PW_ID_BLOCK_REQ;
        unsigned char   answer[256];
        int             i = 0, baud, mybaud = 0, ret = -1;
 
@@ -274,6 +277,10 @@
                send_write_command(AUT, 4);
                usleep(500000);
                ret = command_sequence(&command, 1, answer);
+               if (ret <= 0) {
+                       usleep(500000);
+                       ret = command_sequence(&id_command, 1, answer);
+               }
 
                if (ret > 0) {
                        upslogx(LOG_INFO, "Connected to UPS on %s with baudrate 
%d", port, baud);
@@ -293,6 +300,10 @@
                send_write_command(AUT, 4);
                usleep(500000);
                ret = command_sequence(&command, 1, answer);
+               if (ret <= 0) {
+                       usleep(500000);
+                       ret = command_sequence(&id_command, 1, answer);
+               }
 
                if (ret > 0) {
                        upslogx(LOG_INFO, "Connected to UPS on %s with baudrate 
%d", port, pw_baud_rates[i].name);

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

Reply via email to