--- nut-2.0.5.old/drivers/megatec.c 2007-04-13 18:20:01 +0400 +++ nut-2.0.5.old/drivers/megatec.c 2009-01-06 00:46:35 +0300 @@ -25,10 +25,12 @@ #include "main.h" #include "serial.h" #include "megatec.h" +#include "timehead.h" #include #include #include +#include #define ENDCHAR '\r' @@ -49,10 +51,12 @@ #define MAX_START_DELAY 9999 #define MAX_SHUTDOWN_DELAY 99 +#define MAX_REPEAT_DELAY 15000 /* Maximum length of a string representing these values */ #define MAX_START_DELAY_LEN 4 #define MAX_SHUTDOWN_DELAY_LEN 2 +#define MAX_REPEAT_DELAY_LEN 5 #define N_FLAGS 8 @@ -130,7 +134,10 @@ /* In minutes: */ static short start_delay = 2; /* wait this amount of time to come back online */ -static short shutdown_delay = 0; /* wait until going offline */ +static unsigned char shutdown_delay[3] = ".2"; /* wait until going offline */ + +/* In milliseconds: */ +static short off_cmd_repeat = 0; /* wait this amount of time to repeat off/shutdown command */ /* In percentage: */ static float lowbatt = -1; /* disabled */ @@ -412,7 +419,21 @@ } if (getval("offdelay")) { - shutdown_delay = CLAMP(atoi(getval("offdelay")), 0, MAX_SHUTDOWN_DELAY); + shutdown_delay[2] = '\0'; + strncpy(shutdown_delay, getval("offdelay"), 2); + if (shutdown_delay[0] == '\0') { + shutdown_delay[0] = '.'; + shutdown_delay[1] = '2'; + } else if (shutdown_delay[0] != '.') { + i = CLAMP(atoi(shutdown_delay), 0, MAX_SHUTDOWN_DELAY); + snprintf(shutdown_delay, 2, "%02d", i); + } else if (shutdown_delay[1] == '\0') { + shutdown_delay[1] = '2'; + } + } + + if (getval("cmdrepeat")) { + off_cmd_repeat = CLAMP(atoi(getval("cmdrepeat")), 0, MAX_REPEAT_DELAY); } /* @@ -422,10 +443,14 @@ dstate_setflags("ups.delay.start", ST_FLAG_RW | ST_FLAG_STRING); dstate_setaux("ups.delay.start", MAX_START_DELAY_LEN); - dstate_setinfo("ups.delay.shutdown", "%d", shutdown_delay); + dstate_setinfo("ups.delay.shutdown", "%s", shutdown_delay); dstate_setflags("ups.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING); dstate_setaux("ups.delay.shutdown", MAX_SHUTDOWN_DELAY_LEN); + dstate_setinfo("ups.delay.cmdrepeat", "%d", off_cmd_repeat); + dstate_setflags("ups.delay.cmdrepeat", ST_FLAG_RW | ST_FLAG_STRING); + dstate_setaux("ups.delay.cmdrepeat", MAX_REPEAT_DELAY_LEN); + /* * Register the available instant commands. */ @@ -543,7 +568,11 @@ upslogx(LOG_INFO, "Shutting down UPS immediately."); ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); - ser_send_pace(upsfd, SEND_PACE, "S%02dR%04d%c", shutdown_delay, start_delay, ENDCHAR); + ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); + if (off_cmd_repeat > 0) { + usleep(off_cmd_repeat * 1000); + ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); + } } @@ -598,7 +627,11 @@ ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); watchdog_enabled = 0; - ser_send_pace(upsfd, SEND_PACE, "S%02dR%04d%c", shutdown_delay, start_delay, ENDCHAR); + ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); + if (off_cmd_repeat > 0) { + usleep(off_cmd_repeat * 1000); + ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); + } upslogx(LOG_INFO, "Shutdown (return) initiated."); @@ -609,7 +642,11 @@ ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); watchdog_enabled = 0; - ser_send_pace(upsfd, SEND_PACE, "S%02dR0000%c", shutdown_delay, ENDCHAR); + ser_send_pace(upsfd, SEND_PACE, "S%.2sR0000%c", shutdown_delay, ENDCHAR); + if (off_cmd_repeat > 0) { + usleep(off_cmd_repeat * 1000); + ser_send_pace(upsfd, SEND_PACE, "S%.2sR0000%c", shutdown_delay, ENDCHAR); + } upslogx(LOG_INFO, "Shutdown (stayoff) initiated."); @@ -639,6 +676,10 @@ watchdog_enabled = 0; ser_send_pace(upsfd, SEND_PACE, "S00R0000%c", ENDCHAR); + if (off_cmd_repeat > 0) { + usleep(off_cmd_repeat * 1000); + ser_send_pace(upsfd, SEND_PACE, "S00R0000%c", ENDCHAR); + } upslogx(LOG_INFO, "Turning load off."); @@ -688,12 +729,14 @@ int setvar(const char *varname, const char *val) { int delay; + int i; - if (sscanf(val, "%d", &delay) != 1) { - return STAT_SET_UNKNOWN; - } + i = sscanf(val, "%d", &delay); if (strcasecmp(varname, "ups.delay.start") == 0) { + if (i != 1) { + return STAT_SET_UNKNOWN; + } delay = CLAMP(delay, 0, MAX_START_DELAY); start_delay = delay; dstate_setinfo("ups.delay.start", "%d", delay); @@ -704,9 +747,37 @@ } if (strcasecmp(varname, "ups.delay.shutdown") == 0) { - delay = CLAMP(delay, 0, MAX_SHUTDOWN_DELAY); - shutdown_delay = delay; - dstate_setinfo("ups.delay.shutdown", "%d", delay); + if (!val || !val[0]) { + return STAT_SET_UNKNOWN; + } + if (val[0] != '.' ) { + if (i != 1) { + return STAT_SET_UNKNOWN; + } + delay = CLAMP(delay, 0, MAX_SHUTDOWN_DELAY); + snprintf(shutdown_delay, 2, "%02d", delay); + } else { + i = val[1]; + if (!isdigit(i)) { + return STAT_SET_UNKNOWN; + } + strncpy(shutdown_delay, val, 2); + } + shutdown_delay[2] = '\0'; + dstate_setinfo("ups.delay.shutdown", "%s", shutdown_delay); + + dstate_dataok(); + + return STAT_SET_HANDLED; + } + + if (strcasecmp(varname, "ups.delay.cmdrepeat") == 0) { + if (i != 1) { + return STAT_SET_UNKNOWN; + } + delay = CLAMP(delay, 0, MAX_REPEAT_DELAY); + off_cmd_repeat = delay; + dstate_setinfo("ups.delay.cmdrepeat", "%d", delay); dstate_dataok(); @@ -730,6 +801,7 @@ addvar(VAR_VALUE, "lowbatt", "Low battery level (%)"); addvar(VAR_VALUE, "ondelay", "Delay before UPS startup (minutes)"); addvar(VAR_VALUE, "offdelay", "Delay before UPS shutdown (minutes)"); + addvar(VAR_VALUE, "cmdrepeat", "Delay (msec) to repeat shutdown cmd"); }