[Nut-upsdev] 2.0.3-pre2: Spurious UPS UPS@localhost battery is

Peter Selinger selinger at mathstat.dal.ca
Wed Feb 8 20:48:42 UTC 2006


Hm. I need more information, as NUT seems to garble the values even
before I can see them. I am not so worried about the date and
temperatures (although, strangely, the battery replacement date
appears to be Sept 25, 2001, which makes no sense). But the voltage is
definitely important.

Here is what I need:

1) the output of "./newhidups -u root -DD -a UPS auto 2>&1 | grep
Path" again, but with the attached patch applied, and

2) the output of "get_descriptor 005 003 1 0 0 128 0x22 0" (or
equivalent, substitute own bus and device number instead of 005/003), 
from the attached program. 

The second is so that I can see the raw device descriptor, and
hopefully figure out what units/exponents/conversions this device
specifies.

Thanks, -- Peter

Gordon Rowell wrote:
> 
> Peter Selinger wrote:
> > Hi Gordon,
> 
> Sorry for the delay - life has been busy with getting a release together.
> 
> > Just looking at the numbers, it looks like you might have found a bug
> > in the voltage conversion function that might be related to the
> > signedness/unsignedness of numbers; note that -6301.0 + 65536/10 =
> > 252.6.  The latter could be a legitimate voltage, but seems unusually
> > high for any country (your "nominal" voltage is 230).
> 
> As Charlie said, I believe we are or were nominally 240V. I don't know 
> that the power to my shed is all that "nice".
> 
> > I am also worried about your battery.temperature,  ups.temperature,
> 
> It gets hot in my shed. I'd suspect we might see up to 45C ambient on a 
> really hot day, but not 302F, which would be even more unpleasant.
> 
> > and
> > battery.date. It looks like we might need to tweak the driver a bit
> > for your unit. (This seems to be a different UPS than the one you
> > wrote about last week?)
> 
> Yes - this is my UPS at home. The one last week was at a site I support.
> 
> battery.charge: 100
> battery.charge.low: 10
> battery.charge.warning: 50
> battery.date: 3150/08/01
> battery.mfr.date: 2005/01/20

snip.

> > Could you again run "./drivers/newhidups -u root -DD -a UPS auto" and
> > post the "Path" lines, so that I can see the raw, unconverted values
> > of these variables?
> 
> Path: UPS.PowerSummary.iProduct, Type: Feature, Value: 1.000000
> Path: UPS.PowerSummary.iSerialNumber, Type: Feature, Value: 2.000000
> Path: UPS.PowerSummary.iManufacturer, Type: Feature, Value: 3.000000
> Path: UPS.PowerSummary.iOEMInformation, Type: Feature, Value: 3.000000
> Path: UPS.PowerSummary.iDeviceChemistry, Type: Feature, Value: 4.000000
> Path: UPS.PowerSummary.Rechargeable, Type: Feature, Value: 1.000000
> Path: UPS.PowerSummary.CapacityMode, Type: Feature, Value: 2.000000

snip.
-------------- next part --------------
/* get_descriptor.c: a simple tool to get a descriptor from a USB
   device. Uses the libusb API, see http://libusb.sourceforge.net/doc/.
   */

/* NOTE: don't run this program on your USB mouse or keyboard: it will
   detach the kernel driver and leave your computer pretty useless. */

/* Copyright (C) 2005 Peter Selinger.  

   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, or (at
   your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.
*/

/* Usage: get_descriptor <bus> <device> <configuration> <interface> <altsetting> <endpoint> <descriptor> <index>

   For example "get_descriptor 005 003 1 0 0 128 0x22 0" is what I used
   to get the device descriptor of my USB.
*/

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

/* the next invlude is not mentioned in the libusb documentation, but
   evidently needed */
#include <usb.h>

/* ---------------------------------------------------------------------- */
/* general-purpose auxiliary functions */

/* write a hexdump of buf[0]..buf[len-1] to fout */
void hexdump(FILE *fout, char *buf, int len) {
  int i;

  for (i=0; i<len; i++) {
    if ((i % 24) == 0) {
      fprintf(fout, "\n");
    }
    fprintf(fout, " %02x", (unsigned char)buf[i]);
  }
  fprintf(fout, "\n");
}

/* write an ASCII dump of buf[0]..buf[len-1] to fout */
void asciidump(FILE *fout, char *buf, int len) {
  int i;

  for (i=0; i<len; i++) {
    if ((i % 72) == 0) {
      fprintf(fout, "\n ");
    }
    fprintf(fout, "%c", buf[i] >= 32 && buf[i] < 127 ? buf[i] : '.');
  }
  fprintf(fout, "\n");
}

/* convert string to integer. Return -1 on invalid string. */
int mystrtol(char *s) {
  int r;
  char *p;

  r = strtol(s, &p, 0);
  if (*s == 0 || *p != 0) {
    return -1;
  }
  return r;
}

/* ---------------------------------------------------------------------- */
/* auxiliary USB functions */

/* claim interface, detaching any kernel driver if necessary */
int usb_claim_interface_with_detach(usb_dev_handle *dev, int interface) {
  int r;

  r = usb_claim_interface(dev, interface);

#if LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
  if (r == -EBUSY) {
    r = usb_detach_kernel_driver_np(dev, interface);
    if (r == 0) {
      r = usb_claim_interface(dev, interface);
    }
  }
#endif

  return r;
}

/* ---------------------------------------------------------------------- */
/* user interface */

void usage(FILE *fout, char *myname) {
  fprintf(fout, "Usage: %s <bus> <device> <configuration> <interface> <altsetting> <endpoint> <descriptor> <index>\n", myname);
}

int main(int ac, char *av[]) {
  struct usb_bus *bus;
  struct usb_device *dev;
  struct usb_config_descriptor *con = NULL;
  struct usb_interface *inter = NULL;
  struct usb_interface_descriptor *alt = NULL;
  struct usb_endpoint_descriptor *end;
  int i, r;
  int err = 0;
  char buf[2048];
  usb_dev_handle *udev;
  FILE *fout = stdout;
  char *myname, *arg_bus, *arg_dev;
  int arg_con, arg_int, arg_alt, arg_end, arg_typ, arg_ind;

  /* required initializations */
  usb_init();
  usb_find_busses();
  usb_find_devices();

  myname = av[0];
  av++;
  ac--;

  /* command line options */
  if (ac != 8) {
    fprintf(stderr, "Wrong number of arguments.\n");
    usage(stderr, myname);
    exit(1);
  }
  arg_bus = av[0];
  arg_dev = av[1];
  arg_con = mystrtol(av[2]);
  arg_int = mystrtol(av[3]);
  arg_alt = mystrtol(av[4]);
  arg_end = mystrtol(av[5]);
  arg_typ = mystrtol(av[6]);
  arg_ind = mystrtol(av[7]);

  /* find the requested bus */
  for (bus = usb_get_busses(); bus; bus = bus->next) {
    if (strcmp(bus->dirname, arg_bus) == 0) {
      break;
    }
  }
  if (!bus) {
    fprintf(stderr, "There is no bus %s.\n", arg_bus);
    fprintf(stderr, "Possible values:");
    for (bus = usb_get_busses(); bus; bus = bus->next) {
      fprintf(stderr, " %s", bus->dirname);
    }
    fprintf(stderr, "\n");
    exit(2);
  }

  /* find the requested device */
  for (dev = bus->devices; dev; dev = dev->next) {
    if (strcmp(dev->filename, arg_dev) == 0) {
      break;
    }
  }
  if (!dev) {
    fprintf(stderr, "Bus %s has no device %s.\n", arg_bus, arg_dev);
    fprintf(stderr, "Possible values:");
    for (dev = bus->devices; dev; dev = dev->next) {
      fprintf(stderr, " %s", dev->filename);
    }
    fprintf(stderr, "\n");
    exit(2);
  }

  /* find the requested configuration */
  for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
    con = &dev->config[i];
    if (con->bConfigurationValue == arg_con) {
      break;
    }
  }
  if (i >= dev->descriptor.bNumConfigurations) {
    fprintf(stderr, "Bus %s device %s has no configuration %d.\n", arg_bus, arg_dev, arg_con);
    fprintf(stderr, "Possible values:");
    for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
      con = &dev->config[i];
      fprintf(stderr, " %d", con->bConfigurationValue);
    }
    fprintf(stderr, "\n");
    exit(2);
  }

  /* find the requested interface */
  for (i=0; i<con->bNumInterfaces; i++) {
    inter = &con->interface[i];
    alt = &inter->altsetting[0];
    if (alt->bInterfaceNumber == arg_int) {
      break;
    }
  }
  if (i >= con->bNumInterfaces) {
    fprintf(stderr, "Bus %s device %s configuration %d has no interface %d.\n", arg_bus, arg_dev, arg_con, arg_int);
    fprintf(stderr, "Possible values:");
    for (i=0; i<con->bNumInterfaces; i++) {
      inter = &con->interface[i];
      alt = &inter->altsetting[0];
      fprintf(stderr, " %d", alt->bInterfaceNumber);
    }
    fprintf(stderr, "\n");
    exit(2);
  }
  
  /* find the requested alternative setting */
  for (i=0; i<inter->num_altsetting; i++) {
    alt = &inter->altsetting[i];
    if (alt->bAlternateSetting == arg_alt) {
      break;
    }
  }
  if (i >= inter->num_altsetting) {
    fprintf(stderr, "Bus %s device %s configuration %d interface %d has no altsetting %d.\n", arg_bus, arg_dev, arg_con, arg_int, arg_alt);
    fprintf(stderr, "Possible values:");
    for (i=0; i<inter->num_altsetting; i++) {
      alt = &inter->altsetting[i];
      fprintf(stderr, " %d", alt->bAlternateSetting);
    }
    fprintf(stderr, "\n");
    exit(2);
  }

  /* find the requested endpoint */
  if (arg_end != 128) {
    for (i = 0; i < alt->bNumEndpoints; i++) {
      end = &alt->endpoint[i];
      if (end->bEndpointAddress == arg_end) {
	break;
      }
    }
    if (i >= alt->bNumEndpoints) {
      fprintf(stderr, "Bus %s device %s configuration %d interface %d altsetting %d has no endpoint %d.\n", arg_bus, arg_dev, arg_con, arg_int, arg_alt, arg_end);
      fprintf(stderr, "Possible values: 128");
      for (i = 0; i < alt->bNumEndpoints; i++) {
	end = &alt->endpoint[i];
	fprintf(stderr, " %d", end->bEndpointAddress);
      }
      fprintf(stderr, "\n");
      exit(2);
    }
  }
  
  /* OK, we got all the information. Now try to fetch the descriptor */

  /* open the device */
  udev = usb_open(dev);
  if (!udev) {
    fprintf(fout, "Can't open bus %s device %s: %s\n", arg_bus, arg_dev, usb_strerror());
    exit(3);
  }

  /* set the configuration */
  r = usb_set_configuration(udev, arg_con);
  if (r<0) {
    fprintf(fout, "Warning: %s\n", usb_strerror());
    err = 3;
  }
  
  /* claim the interface */
  r = usb_claim_interface_with_detach(udev, arg_int);
  if (r<0) {
    fprintf(fout, "Warning: %s\n", usb_strerror());
    err = 3;
  }

  /* set altsetting */
  r = usb_set_altinterface(udev, arg_alt);
  if (r<0) {
    fprintf(fout, "Warning: %s\n", usb_strerror());
    err = 3;
  }

  /* get the descriptor for this endpoint, type, index */
  r = usb_get_descriptor_by_endpoint(udev, arg_end, arg_typ, arg_ind, buf, sizeof(buf));
  if (r < 0) {
    fprintf(fout, "Can't get endpoint %d descriptor 0x%02x index %d: %s\n", arg_end, arg_typ, arg_ind, usb_strerror());
    err = 3;
    goto done;
  }
  fprintf(stderr, "Bus %s device %s configuration %d interface %d altsetting %d endpoint %d descriptor 0x%02x index %d:\n", arg_bus, arg_dev, arg_con, arg_int, arg_alt, arg_end, arg_typ, arg_ind);

  hexdump(fout, buf, r);
  asciidump(fout, buf, r);

 done:
  usb_close(udev);

  if (err && getuid() != 0) {
    fprintf(fout, "Try running this program as root, or as the owner of /proc/bus/usb/%s/%s.\n", arg_bus, arg_dev);
  }
  return err;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch0.diff
Type: application/octet-stream
Size: 5849 bytes
Desc: ascii text
Url : http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20060208/32e816e2/patch0.obj


More information about the Nut-upsdev mailing list