[Nut-upsdev] fentonups driver patch for Effekta MHD3000 UPS

Remete Gábor remete at mail.datanet.hu
Mon Jul 24 15:40:40 UTC 2006


Hi ups-devel,

As I looked throw www.networkupstools.org site, haven't found any 
pointers where to send patches, so I hope this is the right place. 
(Please let me know weather this is the right place.)

The patch contains a minor change in the logic of the driver, our 
Effekta MHD 3000 UPS continuously writes status data to the serial port, 
so one has to send a CR character and empty the buffer of the serial 
port before sending command and reading the response. This logic 
trivially works for the other models, but I don't have one to test it.
Other additions include
    - added an is_online member to the modeltabs, stating weather the 
mode is an on-line UPS or not
    - on an on-line UPS the b5 of the status is BYPASS instead of 
BOOST/TRIM so set it in the status
    - set SHUTDOWN and TEST flag is status according to b1 b2
    - added id string to mtab2 for MHD3000

Note the I set the is_online flag for all the existing UPS to 0, so the 
behavior will be the same as before the patch, although probably it is 
wrong. Someone knowing which model are on-line later can set the flags 
correctly.

Please also send the reply to my email, because I'm not on the list.

regards,

Gabor
-------------- next part --------------
*** fentonups.c	2005-05-26 14:22:27.000000000 +0200
--- /usr/src/redhat/BUILD/nut-2.0.3/drivers/fentonups.c	2006-07-24 16:20:19.000000000 +0200
***************
*** 30,38 ****
--- 30,52 ----
  #define	DRV_VERSION "1.22"
  
  static	int	cap_upstemp = 0;
+ static	int	is_online = 0;
  static	float	lowvolt = 0, voltrange, chrglow = 0, chrgrange;
  static	int	lownorm, highnorm;
  
+ static void sendcr_and_clear_buf(void)
+ {
+ 	int ret;
+ 
+ 	ret = ser_send(upsfd, "\r");
+ 
+ 	usleep(300000);
+ 
+ 	if (ret != 1)
+ 		upslog(LOG_ERR, "sendcr_and_clear_buf: ser_send failed");
+ 	ser_flush_in(upsfd, "", 0);
+ }
+ 
  /* handle devices which don't give a properly formatted I string */
  static int check_mtab2(const char *raw)
  {
***************
*** 54,59 ****
--- 68,74 ----
  			chrglow = mtab2[i].chrglow;
  			chrgrange = mtab2[i].chrgrange;
  			cap_upstemp = mtab2[i].has_temp;
+ 			is_online = mtab2[i].is_online;
  
  			dstate_setinfo("input.transfer.low", "%d",
  				mtab2[i].lowxfer);
***************
*** 121,126 ****
--- 136,143 ----
  	int	ret;
  
  	if (!strcasecmp(cmdname, "test.battery.start")) {
+ 		sendcr_and_clear_buf();
+ 
  		ret = ser_send(upsfd, "T\r");
  
  		if (ret != 2)
***************
*** 130,135 ****
--- 147,154 ----
  	}
  
  	if (!strcasecmp(cmdname, "test.battery.stop")) {
+ 		sendcr_and_clear_buf();
+ 
  		ret = ser_send(upsfd, "CT\r");
  
  		if (ret != 2)
***************
*** 149,154 ****
--- 168,175 ----
  
  	/* try to get the initial UPS data */
  	for (i = 0; i < 5; i++) {
+ 		sendcr_and_clear_buf();
+ 
  		ret = ser_send(upsfd, "I\r");
  
  		if (ret != 2)
***************
*** 212,217 ****
--- 233,239 ----
  			chrglow = modeltab[i].chrglow;
  			chrgrange = modeltab[i].chrgrange;
  			cap_upstemp = modeltab[i].has_temp;
+ 			is_online = modeltab[i].is_online;
  			break;
  		}
  	}
***************
*** 240,245 ****
--- 262,269 ----
  	free(raw);
  
  	/* paranoia - cancel any shutdown that might already be running */
+ 	sendcr_and_clear_buf();
+ 
  	ret = ser_send(upsfd, "C\r");
  
  	if (ret != 2)
***************
*** 258,263 ****
--- 282,290 ----
  	double	bvoltp;
  	float   lowbattvolt = 0;
  
+ 	
+ 	sendcr_and_clear_buf();
+ 
  	ret = ser_send(upsfd, "Q1\r");
  
  	if (ret != 3)
***************
*** 320,331 ****
  		status_set("OL");		/* on line */
  
  		/* only allow these when OL since they're bogus when OB */
! 		if (pstat[2] == '1') {		/* boost or trim in effect */
! 			if (util < lownorm)
! 				status_set("BOOST");
! 
! 			if (util > highnorm)
! 				status_set("TRIM");
  		}
  		if (atof(battvolt) > chrglow) {
  			bvoltp = ((atof(battvolt) - chrglow) / chrgrange) * 100.0;
--- 347,363 ----
  		status_set("OL");		/* on line */
  
  		/* only allow these when OL since they're bogus when OB */
! 		if (is_online) {
! 			if(pstat[2] == '1')
! 				status_set("BYPASS");
! 		} else {
! 			if (pstat[2] == '1') {		/* boost or trim in effect */
! 				if (util < lownorm)
! 					status_set("BOOST");
! 
! 				if (util > highnorm)
! 					status_set("TRIM");
! 			}
  		}
  		if (atof(battvolt) > chrglow) {
  			bvoltp = ((atof(battvolt) - chrglow) / chrgrange) * 100.0;
***************
*** 339,344 ****
--- 371,384 ----
  		bvoltp = ((atof(battvolt) - lowvolt) / voltrange) * 100.0;
  	}
  
+ 	if(pstat[5] == '1') {
+ 		status_set("TEST");
+ 	}
+ 
+ 	if(pstat[6] == '1') {
+ 		status_set("SHUTDOWN");
+ 	}
+ 
  	if (bvoltp > 100.0)
  		bvoltp = 100.0;
  	dstate_setinfo("battery.charge", "%02.1f", bvoltp);
***************
*** 370,375 ****
--- 410,417 ----
  	int	ret;
  	char	temp[256], pstat[32];
  
+ 	sendcr_and_clear_buf();
+ 
  	ret = ser_send(upsfd, "Q1\r");
  
  	if (ret != 3) {
***************
*** 411,421 ****
--- 453,465 ----
  		printf("On line, sending shutdown+return command...\n");
  
  		/* return values below 3 misbehave on some hardware revs */
+ 		sendcr_and_clear_buf();
  		ser_send(upsfd, "S01R0003\r");
  		return;
  	}
  
  	printf("On battery, sending normal shutdown command...\n");
+ 	sendcr_and_clear_buf();
  	ser_send(upsfd, "S01\r");
  }
  
*** fentonups.h	2005-07-20 12:45:41.000000000 +0200
--- /usr/src/redhat/BUILD/nut-2.0.3/drivers/fentonups.h	2006-07-24 14:28:18.000000000 +0200
***************
*** 30,71 ****
  	int	highnorm;
  	int	highxfer;
  	int	has_temp;
  }	modeltab[] =
  {
  	/* USA models */
! 	{ "L280A",  "PowerPal 280",  9.6,  2.4, 12.1, 1.7, 84, 98, 126, 142, 0 },
! 	{ "L425A",  "PowerPal 425",  9.6,  2.4, 12.1, 1.7, 84, 98, 126, 142, 0 },	
! 	{ "L660A",  "PowerPal 660",  19.6, 4.4, 24.2, 3.3, 84, 98, 126, 142, 0 },
! 	{ "L1000A", "PowerPal 1000", 19.6, 4.4, 24.2, 3.3, 84, 98, 126, 142, 0 },
! 	{ "L1400A", "PowerPal 1400", 29.4, 6.6, 36.3, 4.7, 84, 98, 126, 142, 0 },
  
  	/* European models */
! 	{ "L280E",  "PowerPal 280",   9.6, 2.4, 12.1, 1.7, 168, 196, 252, 284, 0 },
! 	{ "L425E",  "PowerPal 425",   9.6, 2.4, 12.1, 1.7, 168, 196, 252, 284, 0 },	
! 	{ "L660E",  "PowerPal 660",  19.6, 4.4, 24.2, 3.3, 168, 196, 252, 284, 0 },
! 	{ "L1000E", "PowerPal 1000", 19.6, 4.4, 24.2, 3.3, 168, 196, 252, 284, 0 },
! 	{ "L1400E", "PowerPal 1400", 29.4, 6.6, 36.3, 4.7, 168, 196, 252, 284, 0 },
! 
! 	{ "M1000", "PowerPure 1000", 25.0,  3.4, 25.2,  3.2, 80, 80, 138, 138, 1 },
! 	{ "M2000", "PowerPure 2000",    0,    0,    0,    0, 80, 80, 138, 138, 1 },
! 	{ "M3000", "PowerPure 3000",    0,    0,    0,    0, 80, 80, 138, 138, 1 }, 
! 
! 	{ "H4000", "PowerOn 4000",  154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1 },
! 	{ "H6000", "PowerOn 6000",  154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1 },
! 	{ "H8000", "PowerOn 8000",  154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1 },
! 	{ "H010K", "PowerOn 10000", 154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1 },
  
  	/* non-Fenton, yet compatible (Megatec protocol) models */
  
! 	{ "UPS-PRO", "PowerGuard PG-600", 0, 0, 0, 0, 170, 200, 250, 270, 1 },
  
! 	{ "SMK800A", "PowerCom SMK-800A", 1.9, 0.5, 1.9, 0.5, 165, 200, 240, 275, 1 },
  
! 	{ "ULT-1000", "PowerCom ULT-1000", 1.91, 0.42, 1.91, 0.42, 165, 200, 240, 275, 1 },
  
! 	{ "Alpha500iC", "Alpha 500 iC", 10.7, 1.4, 13.0, 0.8, 172, 196, 252, 288, 0 },
  
! 	{ NULL,    NULL,		  0, 0, 0, 0,   0,   0,   0,   0, 0 }
  };
  
  /* devices which don't implement the I string the same way */
--- 30,72 ----
  	int	highnorm;
  	int	highxfer;
  	int	has_temp;
+ 	int	is_online;
  }	modeltab[] =
  {
  	/* USA models */
! 	{ "L280A",  "PowerPal 280",  9.6,  2.4, 12.1, 1.7, 84, 98, 126, 142, 0, 0 },
! 	{ "L425A",  "PowerPal 425",  9.6,  2.4, 12.1, 1.7, 84, 98, 126, 142, 0, 0 },	
! 	{ "L660A",  "PowerPal 660",  19.6, 4.4, 24.2, 3.3, 84, 98, 126, 142, 0, 0 },
! 	{ "L1000A", "PowerPal 1000", 19.6, 4.4, 24.2, 3.3, 84, 98, 126, 142, 0, 0 },
! 	{ "L1400A", "PowerPal 1400", 29.4, 6.6, 36.3, 4.7, 84, 98, 126, 142, 0, 0 },
  
  	/* European models */
! 	{ "L280E",  "PowerPal 280",   9.6, 2.4, 12.1, 1.7, 168, 196, 252, 284, 0, 0 },
! 	{ "L425E",  "PowerPal 425",   9.6, 2.4, 12.1, 1.7, 168, 196, 252, 284, 0, 0 },	
! 	{ "L660E",  "PowerPal 660",  19.6, 4.4, 24.2, 3.3, 168, 196, 252, 284, 0, 0 },
! 	{ "L1000E", "PowerPal 1000", 19.6, 4.4, 24.2, 3.3, 168, 196, 252, 284, 0, 0 },
! 	{ "L1400E", "PowerPal 1400", 29.4, 6.6, 36.3, 4.7, 168, 196, 252, 284, 0, 0 },
! 
! 	{ "M1000", "PowerPure 1000", 25.0,  3.4, 25.2,  3.2, 80, 80, 138, 138, 1, 0 },
! 	{ "M2000", "PowerPure 2000",    0,    0,    0,    0, 80, 80, 138, 138, 1, 0 },
! 	{ "M3000", "PowerPure 3000",    0,    0,    0,    0, 80, 80, 138, 138, 1, 0 }, 
! 
! 	{ "H4000", "PowerOn 4000",  154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1, 0 },
! 	{ "H6000", "PowerOn 6000",  154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1, 0 },
! 	{ "H8000", "PowerOn 8000",  154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1, 0 },
! 	{ "H010K", "PowerOn 10000", 154.0, 14.0, 154.0, 14.0, 88, 88, 132, 132, 1, 0 },
  
  	/* non-Fenton, yet compatible (Megatec protocol) models */
  
! 	{ "UPS-PRO", "PowerGuard PG-600", 0, 0, 0, 0, 170, 200, 250, 270, 1, 0 },
  
! 	{ "SMK800A", "PowerCom SMK-800A", 1.9, 0.5, 1.9, 0.5, 165, 200, 240, 275, 1, 0 },
  
! 	{ "ULT-1000", "PowerCom ULT-1000", 1.91, 0.42, 1.91, 0.42, 165, 200, 240, 275, 1, 0 },
  
! 	{ "Alpha500iC", "Alpha 500 iC", 10.7, 1.4, 13.0, 0.8, 172, 196, 252, 288, 0, 0 },
  
! 	{ NULL,    NULL,		  0, 0, 0, 0,   0,   0,   0,   0, 0, 0 }
  };
  
  /* devices which don't implement the I string the same way */
***************
*** 83,110 ****
  	int	highnorm;
  	int	highxfer;
  	int	has_temp;
  }	mtab2[] =
  {
! 	{ "WELI 500 1.0", "Giant Power", "MT650", 10.6, 3.7, 12.1, 2.2, 170, 180, 270, 280, 0 },
  	{ "SMART-UPS       1800VA     T18Q16AG", "Effekta", "MT 2000 RM",
! 		50.0, 19.5, 50.0, 19.5, 171, 200, 260, 278, 1 },
  	
  	/* Sysgration model data from Simon J. Rowe */
  	
  	{ "                Pro 650    4.01", "Sysgration", "UPGUARDS Pro650",
! 		9.6, 2.4, 9.6, 2.4, 168, 196, 252, 284, 1 },
  
  	/* SuperPower model data from Denis Zaika */
  
  	{ "----            ----       VS00024Q", "SuperPower", "HP360", 9.6, 
! 		3.9, 9.6, 3.9, 140, 190, 240, 280, 1 },
  	{ " -------------   ------     VS000391", "SuperPower", "Hope-550", 
! 		9.6, 3.9, 9.6, 3.9, 170, 190, 240, 280, 0 },
  
  	/* Unitek data from Antoine Cuvellard */
  	        
  	{ "UNITEK          Alph1000iS A0", "Unitek", "Alpha 1000is",
! 		9.6, 2.4, 9.6, 2.4, 158, 172, 288, 290, 0 },
  
  	{ NULL,    NULL,		NULL,  0, 0,   0,   0,   0,   0, 0 }
  };
--- 84,117 ----
  	int	highnorm;
  	int	highxfer;
  	int	has_temp;
+ 	int	is_online;
  }	mtab2[] =
  {
! 	{ "WELI 500 1.0", "Giant Power", "MT650", 10.6, 3.7, 12.1, 2.2, 170, 180, 270, 280, 0, 0 },
  	{ "SMART-UPS       1800VA     T18Q16AG", "Effekta", "MT 2000 RM",
! 		50.0, 19.5, 50.0, 19.5, 171, 200, 260, 278, 1, 0 },
  	
  	/* Sysgration model data from Simon J. Rowe */
  	
  	{ "                Pro 650    4.01", "Sysgration", "UPGUARDS Pro650",
! 		9.6, 2.4, 9.6, 2.4, 168, 196, 252, 284, 1, 0 },
  
  	/* SuperPower model data from Denis Zaika */
  
  	{ "----            ----       VS00024Q", "SuperPower", "HP360", 9.6, 
! 		3.9, 9.6, 3.9, 140, 190, 240, 280, 1, 0 },
  	{ " -------------   ------     VS000391", "SuperPower", "Hope-550", 
! 		9.6, 3.9, 9.6, 3.9, 170, 190, 240, 280, 0, 0 },
  
  	/* Unitek data from Antoine Cuvellard */
  	        
  	{ "UNITEK          Alph1000iS A0", "Unitek", "Alpha 1000is",
! 		9.6, 2.4, 9.6, 2.4, 158, 172, 288, 290, 0, 0 },
! 
! 	/* Effekta MHD3000 */
! 	        
! 	{ "ON-LINE         3000VA     D30R355", "Effekta", "MHD3000",
! 		1.67, 0.6, 1.67, 0.6, 160, 160, 275, 275, 1, 1 },
  
  	{ NULL,    NULL,		NULL,  0, 0,   0,   0,   0,   0, 0 }
  };


More information about the Nut-upsdev mailing list