diff -Naur nut-2.0.5.old/drivers/megatec.c nut-2.0.5.new/drivers/megatec.c
--- nut-2.0.5.old/drivers/megatec.c	2007-04-13 18:20:01 +0400
+++ nut-2.0.5.new/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 <stdio.h>
 #include <limits.h>
 #include <string.h>
+#include <ctype.h>
 
 
 #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");
 }
 
 
