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;