[Nut-upsdev] Help with USB support for a Kebo UPS-650D

Peter Selinger selinger at mathstat.dal.ca
Wed Sep 28 01:25:09 UTC 2005


Andrew Dancy wrote:
> 
> Apologies - I clean forgot to add the "-u root" switch. Here's the output
> with that switch added - looks more promising!

Indeed, very promising. The important bits are:

Path: ffa00001.ffa00002.ffa10003, Type: Input
Path: ffa00001.ffa00002.ffa10004, Type: Input
Path: ffa00001.ffa00002.ffa10005, Type: Input
Path: ffa00001.ffa00002.ffa10006, Type: Input
Path: ffa00001.ffa00002.ffa10007, Type: Input
Path: ffa00001.ffa00002.ffa10008, Type: Input
Path: ffa00001.ffa00002.ffa10009, Type: Output
Path: ffa00001.ffa00002.ffa1000a, Type: Output
Path: ffa00001.ffa00002.ffa1000b, Type: Output
Path: ffa00001.ffa00002.ffa1000c, Type: Output

The next steps are: 
* see if we can read any data from these variables (see below),
* monitor them to figure out what they might mean (see below), 
* map them to the proper NUT variables and instant commands

> Please also try the program from this post:
> 
> http://lists.alioth.debian.org/pipermail/nut-upsdev/2005-September/000144.ht
> ml
> 
> This is just a simple program that connects to USB devices and prints
> some information about them. Nothing fancy and nothing UPS specific,
> but if this works then there's no reason NUT could not connect to
> it. They must be run as root. Please post the output. 
> 
> -------------
> 
> Tried to compile with gcc -I/usr/include usbtest.c and got the following
> (extract)
> 
> usbtest.c:1: error: syntax error before '--' token
> 
> ...

It looks like you forgot to remove the separator line "--------------"
from the beginning of the file. All those errors are bogus. But this does
not matter any more, since NUT now connects to this device. 

Below is a "stub" subdriver kebo-hid.c. This is not really a complete
subdriver yet, because it does not know what the individual variables
stand for. But it should allow you to experiment. If all goes well,
you should be able to "monitor" the UPS variables with upsd/upsc
and you should be able to write to some of them with upsrw.

For the time being, it is best to run the driver and upsd as root,
because you don't want to get any additional trouble to do with
permissions until this is at least demonstrated to work.

Also, don't run upsmon yet, as you don't want your system to shut down
accidentally.

Also, don't connect your computer's power supply to the UPS yet, as
you need to experiment with how to shut it down, and you don't want
your computer to crash if you succeed. 

You'll probably need to set up ups.conf, upsd.conf, and upsd.users at
this point. Then run some combination of the following:

upsmon -c stop     # to make sure upsmon is not running
upsdrvctl stop     # to make sure no other drivers are running
upsd -c stop       # to make sure upsd is not running

upsd -u root       # run upsd without dropping root privileges
drivers/newhidups -DD -u root -a myups   # or similar...

upsc myups at localhost 
	# to see if you can read any variables, see if they change,
        # guess what they are

upsrw -s kebo.output9=1 -u USERNAME -p PASSWORD myups
	# to see if you can set any variables. Experiment with 
	# different variable/value pairs. USERNAME and PASSWORD
	# are from upsd.users 

The idea is to figure out what the variables are from looking at their
values. For example, a value of 117 or 218 (depending on location) is
likely a voltage, a value of ca. 24 is likely a battery voltage, and a
value such as 4097 is likely a binary status indicator. 

Also, some of the "outputs" are likely settable variables that
initiate things such as shutdown procedures. 

It's possible that your driver won't show any values at all. In this
case, we'll have to fine-tune.

I have not yet seen a UPS device that had "Output" items - usually
there is only "Input" and "Feature". So I am not sure if this will
work. We'll have to wait for the outcomes of your experiments. 

Here's the stub driver, don't forget to remove the separator line:

----------------------------------------------------------------------

/*  kebo-hid.c - data to monitor KEBO USB/HID devices with NUT
 *
 *  Copyright (C)  
 *	2003 - 2005	Arnaud Quette <arnaud.quette at free.fr>
 *      2005            Peter Selinger <selinger at users.sourceforge.net>
 *
 *  Sponsored by MGE UPS SYSTEMS <http://www.mgeups.com>
 *
 *  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
 *  (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
 *
 */

#include "newhidups.h"
#include "kebo-hid.h"
#include "extstate.h" /* for ST_FLAG_STRING */
#include "dstate.h"   /* for STAT_INSTCMD_HANDLED */
#include "common.h"

#define KEBO_HID_VERSION "KEBO HID 0.8"

#define KEBO_VENDORID 0x0925

/* --------------------------------------------------------------- */
/*      Vendor-specific usage table */
/* --------------------------------------------------------------- */

/* KEBO usage table */
usage_lkp_t kebo_usage_lkp[] = {
	{ "KEBO_UPS",	        0xffa00001 },
	{ "KEBO_Data",	        0xffa00002 },
	{ "KEBO_Input3",        0xffa10003 },
	{ "KEBO_Input4",	0xffa10004 },
	{ "KEBO_Input5",	0xffa10005 },
	{ "KEBO_Input6",	0xffa10006 },
	{ "KEBO_Input7",	0xffa10007 },
	{ "KEBO_Input8",	0xffa10008 },
	{ "KEBO_Output9",	0xffa10009 },
	{ "KEBO_Output10",	0xffa1000a },
	{ "KEBO_Output11",	0xffa1000b },
	{ "KEBO_Output12",	0xffa1000c },

	{  "\0", 0x0 }
};

static usage_tables_t kebo_utab[] = {
	kebo_usage_lkp,
	hid_usage_lkp,
	NULL,
};

/* --------------------------------------------------------------- */
/*      HID2NUT lookup table                                       */
/* --------------------------------------------------------------- */

/* HID2NUT lookup table */
static hid_info_t kebo_hid2nut[] = {
  /* Server side variables */
  { "driver.version.internal", ST_FLAG_STRING, sizeof(DRIVER_VERSION), NULL, NULL,
    DRIVER_VERSION, HU_FLAG_ABSENT | HU_FLAG_OK, NULL },
  { "driver.version.data", ST_FLAG_STRING, sizeof(KEBO_HID_VERSION), NULL, NULL,
    KEBO_HID_VERSION, HU_FLAG_ABSENT | HU_FLAG_OK, NULL },
  
  /* Unmapped KEBO items */
  { "kebo.input3", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Input3", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.input4", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Input4", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.input5", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Input5", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.input6", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Input6", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.input7", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Input7", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.input8", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Input8", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.output9", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Output9", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.output10", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Output10", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.output11", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Output11", NULL, "%.0f", HU_FLAG_OK, NULL },
  { "kebo.output12", ST_FLAG_RW, 0, "KEBO_UPS.KEBO_Data.KEBO_Output12", NULL, "%.0f", HU_FLAG_OK, NULL },

  /* end of structure. */
  { NULL, 0, 0, NULL, NULL, NULL, 0, NULL }
};

/* shutdown method for KEBO */
static int kebo_shutdown(int ondelay, int offdelay) {
	/* FIXME */
	upsdebugx(2, "KEBO: Shutdown not implemented - failed.");
	return 0;
}

static char *kebo_format_model(HIDDevice *hd) {
	return hd->Product;
}

static char *kebo_format_mfr(HIDDevice *hd) {
	return hd->Vendor ? hd->Vendor : "KEBO";
}

static char *kebo_format_serial(HIDDevice *hd) {
	return hd->Serial;
}

/* this function allows the subdriver to "claim" a device: return 1 if
 * the device is supported by this subdriver, else 0. */
static int kebo_claim(HIDDevice *hd) {
	if (hd->VendorID == KEBO_VENDORID) {
		return 1;
	} else {
		return 0;
	}
}

subdriver_t kebo_subdriver = {
	KEBO_HID_VERSION,
	kebo_claim,
	kebo_utab,
        kebo_hid2nut,
	kebo_shutdown,
	kebo_format_model,
	kebo_format_mfr,
	kebo_format_serial,
};




More information about the Nut-upsdev mailing list