[Nut-upsdev] Two APC900 UPS on the same usbbus1

Markus Grundmann markus at activezone.de
Tue Jul 16 14:43:45 BST 2019


Hi!

On my FreeBSD 12.0-RELEASE-p7 server I was unable to retrieve the 
correct information from my two UPS. Every time only the first UPS will 
returned when I entering "upsc apc900" or "upsc apc901". I don't know 
why (Bug or configuration issue on my side?!). I have downloaded the 
latest source code and with my "patch" I was able to get the right 
information from each UPS are expected (correct serial no and other).

In my ups.conf I have added the keyword "serial" to identify the right 
UPS.

Whenever I called "lsof -p <pid>" for both "usbhid-ups" processes I 
notice that only the ugen/1.5.0 (aka /dev/usb/1.5.0) device was used. 
After my "patch" the drivers was called corect with the option -x and 
the output of "upsc" reports the right UPS and serialno.

[Drivers after patch]
root 81706   0.0  0.0 11880  3040  -  Ss   15:22       0:00.04 
/usr/local/ups/bin/usbhid-ups -a apc900 -x serial=3B1520X10340
root 83581   0.0  0.0 11880  3040  -  Ss   15:22       0:00.04 
/usr/local/ups/bin/usbhid-ups -a apc901 -x serial=3B1207X25460

[/usr/local/etc/nut/ups.conf]
[apc900]
         driver = usbhid-ups
	port = /dev/usb/1.4.0
	serial = 3B1520X10340
         desc = "APC900-LEFT"

[apc901]
         driver = usbhid-ups
	port = /dev/usb/1.5.0
	serial = 3B1207X25460
         desc = "APC900-RIGHT"
===

The source of drivers/upsdrvctl.c was a little bit enhanced with my 
patch. The structure 'ups_t' contains now a new field labeled 'serial' 
and the argument list becomes a new parameter when "serial" is not NULL. 
That's a quick hack but it work's ;-)

Best regards,
Markus

[Patch/Workaround]
root at netstore:~ # diff -u /root/upsdrvctl.c 
nut-2.7.4/drivers/upsdrvctl.c
--- /root/upsdrvctl.c	2019-07-16 15:23:36.496587000 +0200
+++ nut-2.7.4/drivers/upsdrvctl.c	2015-12-29 13:08:34.000000000 +0100
@@ -33,7 +33,6 @@
  	char	*upsname;
  	char	*driver;
  	char	*port;
-	char	*serial;
  	int	sdorder;
  	int	maxstartdelay;
  	void	*next;
@@ -95,9 +94,6 @@
  			if (!strcmp(var, "port"))
  				tmp->port = xstrdup(val);

-			if (!strcmp(var, "serial"))
-				tmp->serial = xstrdup(val);
-
  			if (!strcmp(var, "maxstartdelay"))
  				tmp->maxstartdelay = atoi(val);

@@ -119,7 +115,6 @@
  	tmp->driver = NULL;
  	tmp->port = NULL;
  	tmp->next = NULL;
-	tmp->serial = NULL;
  	tmp->sdorder = 0;
  	tmp->maxstartdelay = -1;	/* use global value by default */

@@ -129,9 +124,6 @@
  	if (!strcmp(var, "port"))
  		tmp->port = xstrdup(val);

-	if (!strcmp(var, "serial"))
-		tmp->serial = xstrdup(val);
-
  	if (last)
  		last->next = tmp;
  	else
@@ -267,7 +259,6 @@
  {
  	char	*argv[8];
  	char	dfn[SMALLBUF];
-	char 	*tval = NULL;
  	int	ret, arg = 0;
  	int	initial_exec_error = exec_error, drv_maxretry = maxretry;
  	struct stat	fs;
@@ -284,15 +275,6 @@
  	argv[arg++] = (char *)"-a";		/* FIXME: cast away const */
  	argv[arg++] = ups->upsname;

-	if (ups->serial) {
-
-		if ((tval = malloc((strlen(ups->serial)+strlen("serial=")+1) * 
sizeof(char)))) {
-
-			argv[arg++] = (char *)"-x";
-			sprintf(argv[arg++],"serial=%s",ups->serial);
-		}
-	}
-
  	/* stick on the chroot / user args if given to us */
  	if (pt_root) {
  		argv[arg++] = (char *)"-r";	/* FIXME: cast away const */
@@ -330,8 +312,6 @@
  				sleep (retrydelay);
  		}
  	}
-
-	if (tval) free(tval);
  }

  static void help(const char *progname)



More information about the Nut-upsdev mailing list