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;