[Nut-upsdev] [PATCH][RFC] OpenUPS driver

Nicu Pavel npavel at mini-box.com
Tue Nov 20 09:51:39 UTC 2012


Hi all,

I attached a driver for MiniBox openUPS device (
http://www.mini-box.com/OpenUPS) and a dump of the hid usages.
I had the possibility to make a few adjustments to the device firmware for
HID usages, and although I haven't managed to produce a good structure
many issues from previous firmware were at least fixed and new information
added.

ATM the driver only shows pertaining information, and the required firmware
is 1.4 which is not yet released (still under QA).

There is a small issue that I haven't been able to understand why is
happening. Looks like ConfigVoltage, which shows the charging voltage setup
from windows application, isn't correctly parsed (01 99  which is 402 or
4.02V gets interpreted only as 99 which is 153 ):

Report[get]: (2 bytes) => 16 01
Path: UPS.PowerSummary.iManufacturer, Type: Feature, ReportID: 0x16,
Offset: 0, Size: 8, Value: 1
Report[get]: (5 bytes) => 20 99 01 1a 03
Path: UPS.PowerSummary.ConfigVoltage, Type: Feature, ReportID: 0x20,
Offset: 0, Size: 16, Value: 153
Report[buf]: (5 bytes) => 20 99 01 1a 03
Path: UPS.PowerSummary.Voltage, Type: Feature, ReportID: 0x20, Offset: 16,
Size: 16, Value: 7.94


Thanks,
Nicu Pavel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20121120/a44be979/attachment-0001.html>
-------------- next part --------------
Index: scripts/upower/95-upower-hid.rules
===================================================================
--- scripts/upower/95-upower-hid.rules	(revision 3782)
+++ scripts/upower/95-upower-hid.rules	(working copy)
@@ -15,6 +15,7 @@
 ATTRS{idVendor}=="03f0", ENV{UPOWER_VENDOR}="Hewlett Packard"
 ATTRS{idVendor}=="0463", ENV{UPOWER_VENDOR}="Eaton"
 ATTRS{idVendor}=="047c", ENV{UPOWER_VENDOR}="Dell"
+ATTRS{idVendor}=="04d8", ENV{UPOWER_VENDOR}="for getval()"
 ATTRS{idVendor}=="050d", ENV{UPOWER_VENDOR}="Belkin"
 ATTRS{idVendor}=="051d", ENV{UPOWER_VENDOR}="APC"
 ATTRS{idVendor}=="0592", ENV{UPOWER_VENDOR}="Powerware"
@@ -47,6 +48,9 @@
 # Dell
 ATTRS{idVendor}=="047c", ATTRS{idProduct}=="ffff", ENV{UPOWER_BATTERY_TYPE}="ups"
 
+# for getval()
+ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="d004", ENV{UPOWER_BATTERY_TYPE}="ups"
+
 # Belkin
 ATTRS{idVendor}=="050d", ATTRS{idProduct}=="0375", ENV{UPOWER_BATTERY_TYPE}="ups"
 ATTRS{idVendor}=="050d", ATTRS{idProduct}=="0551", ENV{UPOWER_BATTERY_TYPE}="ups"
Index: data/driver.list.in
===================================================================
--- data/driver.list.in	(revision 3782)
+++ data/driver.list.in	(working copy)
@@ -644,6 +644,8 @@
 "Microsol"	"ups"	"5"	"Rhino 10.0"	"10000VA"	"rhino"
 "Microsol"	"ups"	"5"	"Rhino 20.0"	"20000VA"	"rhino"
 
+"Minibox"	"ups"	"5"	"openUPS Intelligent UPS"	"USB port"	"usbhid-ups"
+
 "Mustek"	"ups"	"2"	"Powermust"	"400VA Plus"	"blazer_ser"
 "Mustek"	"ups"	"2"	"Powermust"	"600VA Plus"	"blazer_ser"
 "Mustek"	"ups"	"2"	"Powermust"	"800VA Pro"	"blazer_ser"
Index: drivers/openups-hid.h
===================================================================
--- drivers/openups-hid.h	(revision 0)
+++ drivers/openups-hid.h	(revision 0)
@@ -0,0 +1,81 @@
+/* openups-hid.h - subdriver to monitor openUPS USB/HID devices with NUT
+ *
+ *  Copyright (C)
+ *  2003 - 2009	Arnaud Quette <ArnaudQuette at Eaton.com>
+ *  2005 - 2006	Peter Selinger <selinger at users.sourceforge.net>
+ *  2008 - 2009	Arjen de Korte <adkorte-guest at alioth.debian.org>
+ *         2012	Nicu Pavel <npavel at mini-box.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
+ */
+
+#ifndef OPENUPS_HID_H
+#define OPENUPS_HID_H
+
+#include "usbhid-ups.h"
+
+/* constants for converting HID read values to real values */
+static const float vin_scale = 0.03545 * 100;
+static const float vout_scale = 0.02571 * 100;
+static const float vbat_scale = 0.00857 * 100;
+static const float ccharge_scale = 0.8274 / 10;
+static const float cdischarge_scale = 16.113 / 10;
+
+/* Thermistor table used for temperature lookups 
+ * taken from the windows monitoring application
+ */
+static unsigned int therm_tbl[] = 
+{ 
+	(unsigned int)0x31,
+	(unsigned int)0x40,
+	(unsigned int)0x53,
+	(unsigned int)0x68,
+	(unsigned int)0x82,
+	(unsigned int)0xA0,
+	(unsigned int)0xC3,
+	(unsigned int)0xE9,
+	(unsigned int)0x113,
+	(unsigned int)0x13F,
+	(unsigned int)0x16E,
+	(unsigned int)0x19F,
+	(unsigned int)0x1CF,
+	(unsigned int)0x200,
+	(unsigned int)0x22F,
+	(unsigned int)0x25C,
+	(unsigned int)0x286,
+	(unsigned int)0x2AE,
+	(unsigned int)0x2D3,
+	(unsigned int)0x2F4,
+	(unsigned int)0x312,
+	(unsigned int)0x32D,
+	(unsigned int)0x345,
+	(unsigned int)0x35A,
+	(unsigned int)0x36D,
+	(unsigned int)0x37E,
+	(unsigned int)0x38C,
+	(unsigned int)0x399,
+	(unsigned int)0x3A5,
+	(unsigned int)0x3AF,
+	(unsigned int)0x3B7,
+	(unsigned int)0x3BF,
+	(unsigned int)0x3C6,
+	(unsigned int)0x3CC
+};
+
+static unsigned int therm_tbl_size = sizeof(therm_tbl)/sizeof(therm_tbl[0]);
+
+extern subdriver_t openups_subdriver;
+
+#endif /* OPENUPS_HID_H */
Index: drivers/usbhid-ups.c
===================================================================
--- drivers/usbhid-ups.c	(revision 3782)
+++ drivers/usbhid-ups.c	(working copy)
@@ -37,6 +37,7 @@
 
 /* include all known subdrivers */
 #include "mge-hid.h"
+
 #ifndef SHUT_MODE
 	#include "explore-hid.h"
 	#include "apc-hid.h"
@@ -48,10 +49,14 @@
 	#include "idowell-hid.h"
 #endif
 
+#include "openups-hid.h"
+
 /* master list of avaiable subdrivers */
 static subdriver_t *subdriver_list[] = {
+
 #ifndef SHUT_MODE
 	&explore_subdriver,
+	&openups_subdriver,
 #endif
 	&mge_subdriver,
 #ifndef SHUT_MODE
Index: drivers/Makefile.am
===================================================================
--- drivers/Makefile.am	(revision 3782)
+++ drivers/Makefile.am	(working copy)
@@ -159,7 +159,7 @@
 skel_LDADD = $(LDADD_DRIVERS)
 
 # USB
-USBHID_UPS_SUBDRIVERS = apc-hid.c belkin-hid.c cps-hid.c explore-hid.c \
+USBHID_UPS_SUBDRIVERS = openups-hid.c apc-hid.c belkin-hid.c cps-hid.c explore-hid.c \
  liebert-hid.c mge-hid.c powercom-hid.c tripplite-hid.c idowell-hid.c
 usbhid_ups_SOURCES = usbhid-ups.c libhid.c libusb.c hidparser.c	\
  usb-common.c $(USBHID_UPS_SUBDRIVERS)
@@ -237,7 +237,7 @@
  powercom.h powerpanel.h powerp-bin.h powerp-txt.h powerware-mib.h raritan-pdu-mib.h	\
  safenet.h serial.h snmp-ups.h solis.h tripplite.h tripplite-hid.h 			\
  upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h \
- apcsmart.h apcsmart_tabs.h apcsmart-old.h cyberpower-mib.h
+ apcsmart.h apcsmart_tabs.h apcsmart-old.h cyberpower-mib.h openups-hid.h
 
 # Define a dummy library so that Automake builds rules for the
 # corresponding object files.  This library is not actually built,
Index: drivers/openups-hid.c
===================================================================
--- drivers/openups-hid.c	(revision 0)
+++ drivers/openups-hid.c	(revision 0)
@@ -0,0 +1,315 @@
+/* openups-hid.c - subdriver to monitor openUPS USB/HID devices with NUT
+ *
+ *  Copyright (C)
+ *  2003 - 2012	Arnaud Quette <ArnaudQuette at Eaton.com>
+ *  2005 - 2006	Peter Selinger <selinger at users.sourceforge.net>
+ *  2008 - 2009	Arjen de Korte <adkorte-guest at alioth.debian.org>
+ *         2012	Nicu Pavel <npavel at mini-box.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 "usbhid-ups.h"
+#include "openups-hid.h"
+#include "main.h"		/* for getval() */
+#include "usb-common.h"
+
+#define OPENUPS_HID_VERSION	"openUPS HID 0.1"
+#define OPENUPS_VENDORID	0x04d8
+
+static char openups_scratch_buf[20];
+
+/* USB IDs device table */
+static usb_device_id_t openups_usb_device_table[] = {
+	/* openUPS  minimum required firmware 1.4 */
+	{USB_DEVICE(OPENUPS_VENDORID, 0xd004), NULL},
+
+	/* Terminating entry */
+	{-1, -1, NULL}
+};
+
+static const char *openups_charging_fun(double value);
+static const char *openups_discharging_fun(double value);
+static const char *openups_online_fun(double value);
+static const char *openups_nobattery_fun(double value);
+static const char *openups_off_fun(double value);
+
+static const char *openups_scale_vin_fun(double value);
+static const char *openups_scale_vout_fun(double value);
+static const char *openups_scale_vbat_fun(double value);
+static const char *openups_scale_ccharge_fun(double value);
+static const char *openups_scale_cdischarge_fun(double value);
+static const char *openups_temperature_fun(double value);
+
+static info_lkp_t openups_charging_info[] = {
+	{0, NULL, openups_charging_fun}
+};
+
+static info_lkp_t openups_discharging_info[] = {
+	{0, NULL, openups_discharging_fun}
+};
+
+static info_lkp_t openups_online_info[] = {
+	{0, NULL, openups_online_fun}
+};
+
+static info_lkp_t openups_nobattery_info[] = {
+	{0, NULL, openups_nobattery_fun}
+};
+
+static info_lkp_t openups_off_info[] = {
+	{0, NULL, openups_off_fun}
+};
+
+static info_lkp_t openups_vin_info[] = {
+	{0, NULL, openups_scale_vin_fun}
+};
+
+static info_lkp_t openups_vout_info[] = {
+	{0, NULL, openups_scale_vout_fun}
+};
+
+static info_lkp_t openups_vbat_info[] = {
+	{0, NULL, openups_scale_vbat_fun}
+};
+
+static info_lkp_t openups_ccharge_info[] = {
+	{0, NULL, openups_scale_ccharge_fun}
+};
+
+static info_lkp_t openups_cdischarge_info[] = {
+	{0, NULL, openups_scale_cdischarge_fun}
+};
+
+static info_lkp_t openups_temperature_info[] = {
+	{0, NULL, openups_temperature_fun}
+};
+
+static const char *openups_charging_fun(double value)
+{
+	return value ? "chrg" : "!chrg";
+}
+
+static const char *openups_discharging_fun(double value)
+{
+	return value ? "dischrg" : "!dischrg";
+}
+
+static const char *openups_online_fun(double value)
+{
+	return value ? "online" : "!online";
+}
+
+static const char *openups_nobattery_fun(double value)
+{
+	return value ? "nobattery" : "!nobattery";
+}
+
+static const char *openups_off_fun(double value)
+{
+	return value ? "!off" : "off";
+}
+
+static const char *openups_scale_vin_fun(double value)
+{
+	snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%.2f", value * vin_scale);
+	return openups_scratch_buf;
+}
+
+static const char *openups_scale_vout_fun(double value)
+{
+	snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%.2f", value * vout_scale);
+	return openups_scratch_buf;
+}
+
+static const char *openups_scale_vbat_fun(double value)
+{
+	snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%.2f", value * vbat_scale);
+	return openups_scratch_buf;
+}
+
+static const char *openups_scale_ccharge_fun(double value)
+{
+	snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%.3f", value * ccharge_scale);
+	return openups_scratch_buf;
+}
+
+static const char *openups_scale_cdischarge_fun(double value)
+{
+	snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%.3f", value * cdischarge_scale);
+	return openups_scratch_buf;
+}
+
+static const char *openups_temperature_fun(double value)
+{
+	int i;
+	int pos = -1;
+	unsigned int thermistor = value * 100;
+
+	if (thermistor <= therm_tbl[0]) {
+		snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%d", -40);
+	} else {
+		if (thermistor >= therm_tbl[therm_tbl_size - 1]) {
+			snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%d", 125);
+		} else {
+			for (i = therm_tbl_size - 1; i >= 0; i--) {
+				if (thermistor >= therm_tbl[i]) {
+					pos = i;
+					break;
+				}
+			}
+
+			if (thermistor == therm_tbl[pos]) {
+				snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%d", pos * 5 - 40);
+			} else {
+				int t1 = pos * 5 - 40;
+				int t2 = (pos + 1) * 5 - 40;
+
+				unsigned int d1 = therm_tbl[pos];
+				unsigned int d2 = therm_tbl[pos + 1];
+
+				float temp = (float) (thermistor - d1) * (t2 - t1) / (d2 - d1) + t1;
+				snprintf(openups_scratch_buf, sizeof(openups_scratch_buf), "%.2f", temp);
+			}
+		}
+	}
+
+	return openups_scratch_buf;
+}
+
+/* --------------------------------------------------------------- */
+/*      Vendor-specific usage table */
+/* --------------------------------------------------------------- */
+
+/* OPENUPS usage table */
+static usage_lkp_t openups_usage_lkp[] = {
+	{"Cell1", 0x00000001},	/* Battery cell 1 on J6 pin 1 */
+	{"Cell2", 0x00000002},	/* Battery cell 2 on J6 pin 2 */
+	{"Cell3", 0x00000003},	/* Battery cell 3 on J6 pin 3 */
+	{"Cell4", 0x00000004},	/* Battery cell 4 on J6 pin 4 */
+	{"Cell5", 0x00000005},	/* Battery cell 5 on J6 pin 5 */
+	{"Cell6", 0x00000006},	/* Battery cell 6 on J4 pin 1 */
+	/* Usage table for windows monitoring app only updates when 
+	 * certain request codes are written to USB endpoint */
+	/*{ "OpenUPSExtra", 0xff000001 }, */
+	{NULL, 0}
+};
+
+static usage_tables_t openups_utab[] = {
+	openups_usage_lkp,
+	hid_usage_lkp,
+	NULL,
+};
+
+/* --------------------------------------------------------------- */
+/* HID2NUT lookup table                                            */
+/* --------------------------------------------------------------- */
+
+static hid_info_t openups_hid2nut[] = {
+	{"ups.serial", 0, 0, "UPS.PowerSummary.iSerialNumber", NULL, "%s", 0, stringid_conversion},
+
+	/* Battery */
+	{"battery.type", 0, 0, "UPS.PowerSummary.iDeviceChemistry", NULL, "%s", HU_FLAG_STATIC, stringid_conversion},
+	{"battery.mfr.date", 0, 0, "UPS.PowerSummary.iOEMInformation", NULL, "%s", 0, stringid_conversion},
+	{"battery.voltage", 0, 0, "UPS.PowerSummary.Voltage", NULL, "%.2f", HU_FLAG_QUICK_POLL, NULL},
+	/* { "battery.voltage.nominal", 0, 0, "UPS.PowerSummary.ConfigVoltage", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info }, */
+	{"battery.current", 0, 0, "UPS.PowerSummary.Current", NULL, "%.3f", HU_FLAG_QUICK_POLL, NULL},
+	{"battery.capacity", 0, 0, "UPS.PowerSummary.DesignCapacity", NULL, "%.0f", HU_FLAG_STATIC, NULL},
+	{"battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", NULL, "%.0f", HU_FLAG_QUICK_POLL, NULL},
+	{"battery.charge.low", 0, 0, "UPS.PowerSummary.RemainingCapacityLimit", NULL, "%.0f", HU_FLAG_QUICK_POLL, NULL},
+	{"battery.charge.warning", 0, 0, "UPS.PowerSummary.WarningCapacityLimit", NULL, "%.0f", 0, NULL},
+	{"battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", NULL, "%.0f", HU_FLAG_QUICK_POLL, NULL},
+	{"battery.temperature", 0, 0, "UPS.PowerSummary.Temperature", NULL, NULL, HU_FLAG_QUICK_POLL, openups_temperature_info},
+	{"battery.cell1.voltage", 0, 0, "UPS.PowerSummary.Battery.Cell1", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info},
+	{"battery.cell2.voltage", 0, 0, "UPS.PowerSummary.Battery.Cell2", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info},
+	{"battery.cell3.voltage", 0, 0, "UPS.PowerSummary.Battery.Cell3", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info},
+	{"battery.cell4.voltage", 0, 0, "UPS.PowerSummary.Battery.Cell4", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info},
+	{"battery.cell5.voltage", 0, 0, "UPS.PowerSummary.Battery.Cell5", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info},
+	{"battery.cell6.voltage", 0, 0, "UPS.PowerSummary.Battery.Cell6", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vbat_info},
+
+	/* Output */
+	{"output.voltage", 0, 0, "UPS.PowerSummary.Output.Voltage", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vout_info},
+	{"output.current", 0, 0, "UPS.PowerSummary.Output.Current", NULL, NULL, HU_FLAG_QUICK_POLL, openups_cdischarge_info},
+
+	/* Input */
+	{"input.voltage", 0, 0, "UPS.PowerSummary.Input.Voltage", NULL, NULL, HU_FLAG_QUICK_POLL, openups_vin_info},
+	{"input.current", 0, 0, "UPS.PowerSummary.Input.Current", NULL, NULL, HU_FLAG_QUICK_POLL, openups_ccharge_info},
+
+	/* Status */
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.Good", NULL, NULL, HU_FLAG_QUICK_POLL, openups_off_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.InternalFailure", NULL, NULL, HU_FLAG_QUICK_POLL, commfault_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.Overload", NULL, NULL, HU_FLAG_QUICK_POLL, overload_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.OverTemperature", NULL, NULL, HU_FLAG_QUICK_POLL, overheat_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.ShutdownImminent", NULL, NULL, HU_FLAG_QUICK_POLL, shutdownimm_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit", NULL, NULL, HU_FLAG_QUICK_POLL, lowbatt_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.RemainingTimeLimitExpired", NULL, NULL, HU_FLAG_QUICK_POLL, timelimitexpired_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.Charging", NULL, NULL, HU_FLAG_QUICK_POLL, openups_charging_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.Discharging", NULL, NULL, HU_FLAG_QUICK_POLL, openups_discharging_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.NeedReplacement", NULL, NULL, 0, replacebatt_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", NULL, NULL, HU_FLAG_QUICK_POLL, openups_online_info},
+	{"BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.BatteryPresent", NULL, NULL, HU_FLAG_QUICK_POLL, openups_nobattery_info},
+
+	/* end of structure. */
+	{NULL, 0, 0, NULL, NULL, NULL, 0, NULL}
+};
+
+static const char *openups_format_model(HIDDevice_t * hd)
+{
+	return hd->Product;
+}
+
+static const char *openups_format_mfr(HIDDevice_t * hd)
+{
+	return hd->Vendor ? hd->Vendor : "openUPS";
+}
+
+static const char *openups_format_serial(HIDDevice_t * 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 openups_claim(HIDDevice_t * hd)
+{
+	int status = is_usb_device_supported(openups_usb_device_table, hd);
+
+	switch (status) {
+	case POSSIBLY_SUPPORTED:
+		/* by default, reject, unless the productid option is given */
+		if (getval("productid")) {
+			return 1;
+		}
+		possibly_supported("openUPS", hd);
+		return 0;
+
+	case SUPPORTED:
+		return 1;
+
+	case NOT_SUPPORTED:
+	default:
+		return 0;
+	}
+}
+
+subdriver_t openups_subdriver = {
+	OPENUPS_HID_VERSION,
+	openups_claim,
+	openups_utab,
+	openups_hid2nut,
+	openups_format_model,
+	openups_format_mfr,
+	openups_format_serial,
+};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openups-dump-usages.txt.gz
Type: application/x-gzip
Size: 4330 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20121120/a44be979/attachment-0001.bin>


More information about the Nut-upsdev mailing list