*** drivers/bcmxcp.c	Fri Dec 24 13:24:30 2010
--- drivers/bcmxcp-RW.c	Tue Sep  6 12:16:25 2011
***************
*** 19,24 ****
--- 19,26 ----
  
   ojw0000 2007Apr5 Oliver Wilcock - modified to control individual load segments (outlet.2.shutdown.return) on Powerware PW5125.
  
+  Modified to support setvar for outlet.n.delay.start by Rich Wrenn (RFW) 9-3-11.
+ 
  This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
***************
*** 120,126 ****
  #include "bcmxcp.h"
  
  #define DRIVER_NAME	"BCMXCP UPS driver"
! #define DRIVER_VERSION	"0.23"
  
  /* driver description structure */
  upsdrv_info_t upsdrv_info = {
--- 122,131 ----
  #include "bcmxcp.h"
  
  #define DRIVER_NAME	"BCMXCP UPS driver"
! #define DRIVER_VERSION	"0.24"                      /* Modified RFW 9-6-11 */
! 
! #define MAX_NUT_NAME_LENGTH     128                 /* Added RFW 9-3-11 */
! #define NUT_OUTLET_POSITION     7                   /* Added RFW 9-3-11 */
  
  /* driver description structure */
  upsdrv_info_t upsdrv_info = {
***************
*** 148,153 ****
--- 153,159 ----
  static void decode_meter_map_entry(const unsigned char *entry, const unsigned char format, char* value);
  static int init_outlet(unsigned char len);
  static int instcmd(const char *cmdname, const char *extra);
+ static int setvar (const char *varname, const char *val);   /* Added RFW 9-3-11 */
  
  
  const char *FreqTol[3] = {"+/-2%", "+/-5%", "+/-7"};
***************
*** 912,917 ****
--- 918,925 ----
  		upsdebugx(2, "Auto delay on: %d\n", auto_dly_on);
  		snprintf(outlet_name, sizeof(outlet_name)-1, "outlet.%d.delay.start", num);
  		dstate_setinfo(outlet_name, "%d", auto_dly_on);
+         dstate_setflags(outlet_name, ST_FLAG_RW | ST_FLAG_STRING);  /* Added RFW 9-3-11 */
+         dstate_setaux(outlet_name, 5);                              /* Added RFW 9-3-11 */
  	}
  
  	return num_outlet;
***************
*** 1217,1222 ****
--- 1225,1231 ----
  	dstate_addcmd("test.battery.start");
  
  	upsh.instcmd = instcmd;
+     upsh.setvar = setvar;       /* Added RFW 9-3-11 */
  
  	return;
  }
***************
*** 1663,1665 ****
--- 1672,1756 ----
  	addvar(VAR_VALUE, "baud_rate", "Specify communication speed (ex: 9600)");
  }
  
+ /*
+  *  Above this point in this file is the stock bcmxcp.c from NUT 2.6.0 except as noted.
+  *  Below this point in this file is code added by RFW 9-3-11.
+  */
+ 
+ int setvar (const char *varname, const char *val)
+ {
+ 	unsigned char answer[5], cbuf[5];
+     char namebuf[MAX_NUT_NAME_LENGTH];
+ 	int res, sec, outlet_num;
+ 
+ 	upsdebugx(1, "entering setvar(%s, %s)", varname, val);
+ 
+     strncpy(namebuf, varname, sizeof(namebuf));
+     namebuf[NUT_OUTLET_POSITION] = 'n'; /* Assumes a maximum of 9 outlets */
+ 
+     if (!strcasecmp(namebuf, "outlet.n.delay.start")) {
+ 
+         if (outlet_block_len <= 8) {
+ 			return STAT_SET_INVALID;
+         }
+         
+ 		send_write_command(AUTHOR, 4);
+ 		sleep (1);	/* Need to. Have to wait at least 0.25 sec max 16 sec */
+ 
+         outlet_num = varname[NUT_OUTLET_POSITION] - '0';
+         if (outlet_num < 1 || outlet_num > 9) {
+             return STAT_SET_INVALID;
+         }
+ 
+ 		sec = atoi(val);
+         if (sec < -1 || sec > 0x7FFF) {
+             return STAT_SET_INVALID;
+         }
+ 
+ 		cbuf[0] = PW_SET_OUTLET_COMMAND;    /* Cmd */
+ 		cbuf[1] = 0x02;	                    /* Set Auto On Delay */
+ 		cbuf[2] = outlet_num;               /* Outlet number */
+ 		cbuf[3] = sec&0xff;	                /* Delay in seconds LSB */
+ 		cbuf[4] = sec>>8;	                /* Delay in seconds MSB */
+ 
+ 		res = command_write_sequence(cbuf, 5, answer);
+ 		if (res <= 0) {
+ 			upslogx(LOG_ERR, "Short read from UPS");
+ 			dstate_datastale();
+ 			return -1;
+ 		}
+ 
+ 		switch ((unsigned char) answer[0]) {
+ 
+ 			case 0x31: {
+ 				upslogx(LOG_NOTICE,"Outlet %d start delay set to %d sec", outlet_num, sec);
+ 		        dstate_setinfo(varname, "%d", sec);
+ 				return STAT_SET_HANDLED;
+ 				break;
+ 				}
+ 			case 0x33: {
+ 				upslogx(LOG_NOTICE, "Set [%s] failed due to UPS busy", varname);
+ 				return STAT_SET_UNKNOWN;
+ 				break;
+ 				}
+ 			case 0x35: {
+ 				upslogx(LOG_NOTICE, "Set [%s %s] failed due to parameter out of range", varname, val);
+ 				return STAT_SET_UNKNOWN;
+ 				break;
+ 				}
+ 			case 0x36: {
+ 				upslogx(LOG_NOTICE, "Set [%s %s] failed due to invalid parameter", varname, val);
+ 				return STAT_SET_UNKNOWN;
+ 				break;
+ 				}
+ 			default: {
+ 				upslogx(LOG_NOTICE, "Set [%s] not supported", varname);
+ 				return STAT_SET_FAILED;
+ 				break;
+ 				}
+ 		}
+ 	}
+ 	return STAT_SET_INVALID;
+ }
+ 
+ 
