Package: nut
Version: squeeze
Severity: normal
Tags: patch

I got the following ups:

ups.id: EXtreme 3000 250
ups.mfr: MGE UPS SYSTEMS
ups.model: EXtreme 3000

it reports the following values

driver.parameter.LowBatt: 50
battery.charge.low: 20

the first value is due to the LowBatt setting in ups.conf, the second
probably because the UPS refuses to change it. "initups: Low Battery
Level cannot be set" is what the driver outputs with -D set.

The problem is, that, when discharging the UPS, the transition OB -> LB
comes in too late.

The attached patch makes mge-utalk catch this condition:
in the described case it reads the battery level instead of the status
bit and set_status(LB) when it makes sense.
its quite a hack, but not changing anything when LowBatt is not
set or the UPS behaves as it should.

thank you.
felix
--- mge-utalk-orig.c    2010-08-31 09:29:56.000000000 +0200
+++ mge-utalk.c 2010-08-31 09:46:01.000000000 +0200
@@ -50,6 +50,9 @@
  * 
  * enable_ups_comm() is called before each attempt to read/write data
  * from/to the UPS to re synchronise the communication.
+ *
+ * If the UPS refuses to set the LowBatt level at startup as configured,
+ * the reported LB status bit will be derived from the current battery level.
  */
 
 #include <ctype.h>
@@ -58,13 +61,14 @@
 #include "main.h"
 #include "serial.h"
 #include "mge-utalk.h"
+#include "stdbool.h"
 
 /* --------------------------------------------------------------- */
 /*                  Define "technical" constants                   */
 /* --------------------------------------------------------------- */
 
 #define DRIVER_NAME    "MGE UPS SYSTEMS/U-Talk driver"
-#define DRIVER_VERSION "0.89"
+#define DRIVER_VERSION "0.89-lowbatt"
 
 
 /* driver description structure */
@@ -102,6 +106,7 @@ upsdrv_info_t upsdrv_info = {
 #define SD_STAYOFF     1
 
 int sdtype = SD_RETURN;
+bool LB_trust_ups = true;
 static time_t lastpoll; /* Timestamp the last polling */
 
 /* --------------------------------------------------------------- */
@@ -185,7 +190,10 @@ void upsdrv_initups(void)
                if(!strcmp(buf, "OK"))
                        upsdebugx(1, "Low Battery Level set to %d%%", 
mge_ups.LowBatt);
                else
+               {
                        upsdebugx(1, "initups: Low Battery Level cannot be 
set");
+                       LB_trust_ups = false;
+               }
        }
 
         /* Try to set "ON delay" (if supported and given) */
@@ -269,7 +277,8 @@ void upsdrv_initinfo(void)
                        if(bytes_rcvd > 0 && buf[0] != '?') {
                          upsdebugx(1, "initinfo: Si == >%s<", buf);
 
-                         printf("\nCAUTION : This is an older model. It may 
not support too much polling.\nPlease read man mge-utalk and use 
pollinterval\n");
+                         printf("\nCAUTION : This is an older model. It may 
not support too much polling.\n"
+                                         "Please read man mge-utalk and use 
poll_interval\n");
 
                          p = strchr(buf, ' ');
 
@@ -296,8 +305,8 @@ void upsdrv_initinfo(void)
                          }
 
                          if( model == NULL )
-                               printf("No model found by that model and 
version ID\nPlease contact us with UPS model, name and reminder info\nReminder 
info : Data1=%i , Data2=%i\n", si_data1, si_data2);
-
+                               printf("No model found by that model and 
version ID\nPlease contact us with UPS model,"
+                                               " name and reminder 
info\nReminder info : Data1=%i , Data2=%i\n", si_data1, si_data2);
                        }
                  }
 
@@ -686,7 +695,36 @@ static void extract_info(const char *buf
 }
 
 
+/* --------------------------------------------------------------- */
+/* use reported level to calculate status */
+bool LB_by_level(){
+       char buf[BUFFLEN];
+       char infostr[32];
+       mge_info_item_t level_item = mge_info[0];
+       int chars_rcvd = mge_command(buf, sizeof(buf), level_item.cmd);
+
+       if ( chars_rcvd < 1 || buf[0] == '?' ) {
+               return(true); // to be sure...
+       } else {
+               level_item.ok = TRUE;
+               extract_info(buf, &level_item, infostr, sizeof(infostr));
+               dstate_setinfo(level_item.type, infostr);
+               dstate_setflags(level_item.type, level_item.flags);
+               upsdebugx(1, "initinfo: %s == >%s<", level_item.type, infostr);
+
+               /* Set max length for strings */
+               if (level_item.flags & ST_FLAG_STRING)
+                       dstate_setaux(level_item.type, level_item.length);
+               if ( atoi( getval ("lowbatt") ) < atoi(infostr)) {
+                       upsdebugx(1, "not lowbatt >%s<", infostr );
+                       return(false);
+               }else {
+                       upsdebugx(1, "lowbatt >%s<", infostr );
+                       return(true);
+               }
 
+       }
+}
 /* --------------------------------------------------------------- */
 
 /* get system status, at least: OB, OL, LB
@@ -733,8 +771,15 @@ static int get_ups_status(void)
                        else
                                status_set("OL");
 
-                       if (buf[4] == '1')
-                               status_set("LB");
+                       if ( LB_trust_ups ){
+                               if (buf[4] == '1')
+                                       status_set("LB");
+                       } else {
+                               if(LB_by_level())
+                                       status_set("LB");
+
+                       }
+                          
 
                        if (buf[3] == '1') {
                                rb_set = TRUE;

Reply via email to