[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