[Nut-upsuser] Help with newhidups subdriver for Dynex UPS
M.A.E. Hanson
hansonorders at verizon.net
Sat Nov 11 02:50:49 CET 2006
Hello everyone!
If this message was posted twice, my apologies. I'm having issues with my webmail today...
I am using the testing version of NUT from SVN at changeset 582. I have successfully created a stub for newhidups driver for my Dynex DX-800U UPS, but I am completely lost on the customization of it. I've followed the hid-subdrivers.txt instructions and I understand I need to map all the "unmapped.*" lines of my dynex-hid.c to NUT functions. However, I can't make heads or tails of what I'm supposed to change. Can someone take some time to help a struggling noob? Here's some info I hope helps:
# /usr/src/nut-testing# pico /usr/local/ups/etc/ups.conf
[mythbox]
driver = newhidups
port = /dev/usb/hiddev0
desc = "Living Room"
<<EOF>>
/usr/src/nut-testing# drivers/newhidups -DD -u root /dev/usb/hiddev0
debug level is '2'
Checking device (0000/0000) (005/001)
- VendorID: 0000
- ProductID: 0000
- Manufacturer: Linux 2.6.15-chw-2 ehci_hcd
- Product: EHCI Host Controller
- Serial Number: 0000:00:1d.7
- Bus: 005
Trying to match device
Device does not match - skipping
Checking device (0000/0000) (004/001)
- VendorID: 0000
- ProductID: 0000
- Manufacturer: Linux 2.6.15-chw-2 uhci_hcd
- Product: UHCI Host Controller
- Serial Number: 0000:00:1d.3
- Bus: 004
Trying to match device
Device does not match - skipping
Checking device (0000/0000) (003/001)
- VendorID: 0000
- ProductID: 0000
- Manufacturer: Linux 2.6.15-chw-2 uhci_hcd
- Product: UHCI Host Controller
- Serial Number: 0000:00:1d.2
- Bus: 003
Trying to match device
Device does not match - skipping
Checking device (0000/0000) (002/001)
- VendorID: 0000
- ProductID: 0000
- Manufacturer: Linux 2.6.15-chw-2 uhci_hcd
- Product: UHCI Host Controller
- Serial Number: 0000:00:1d.1
- Bus: 002
Trying to match device
Device does not match - skipping
Checking device (0764/0501) (001/003)
- VendorID: 0764
- ProductID: 0501
- Manufacturer: CPS
- Product: DX-800U
- Serial Number: unknown
- Bus: 001
Trying to match device
Device matches
HID descriptor retrieved (Reportlen = 374)
Report descriptor retrieved (Reportlen = 374)
Found HID device
Network UPS Tools: 0.28 USB communication driver 0.28 - core 0.30 (2.1.0)
Report Descriptor size = 374
Detected a UPS: CPS/DX-800U
Using subdriver: APC/CyberPower HID 0.9
Path: UPS.PowerSummary.iProduct, Type: Feature, Value: 1.000000
Path: UPS.PowerSummary.iSerialNumber, Type: Feature, Value: 2.000000
Path: UPS.PowerSummary.iDeviceChemistry, Type: Feature, Value: 4.000000
Path: UPS.PowerSummary.iOEMInformation, Type: Feature, Value: 3.000000
Path: UPS.PowerSummary.Rechargeable, Type: Feature, Value: 1.000000
Path: UPS.PowerSummary.CapacityMode, Type: Feature, Value: 2.000000
Path: UPS.PowerSummary.DesignCapacity, Type: Feature, Value: 100.000000
Path: UPS.PowerSummary.CapacityGranularity1, Type: Feature, Value: 5.000000
Path: UPS.PowerSummary.CapacityGranularity2, Type: Feature, Value: 10.000000
Path: UPS.PowerSummary.WarningCapacityLimit, Type: Feature, Value: 20.000000
Path: UPS.PowerSummary.RemainingCapacityLimit, Type: Feature, Value: 10.000000
Path: UPS.PowerSummary.FullChargeCapacity, Type: Feature, Value: 100.000000
Path: UPS.PowerSummary.RemainingCapacity, Type: Input, Value: 120.000000
Path: UPS.PowerSummary.RemainingCapacity, Type: Feature, Value: 120.000000
Path: UPS.PowerSummary.RunTimeToEmpty, Type: Input, Value: 240.000000
Path: UPS.PowerSummary.RunTimeToEmpty, Type: Feature, Value: 240.000000
Path: UPS.PowerSummary.RemainingTimeLimit, Type: Input, Value: 300.000000
Path: UPS.PowerSummary.RemainingTimeLimit, Type: Feature, Value: 300.000000
Path: UPS.PowerSummary.ConfigVoltage, Type: Feature, Value: 12.000000
Path: UPS.PowerSummary.Voltage, Type: Feature, Value: 21.200001
Path: UPS.PowerSummary.PresentStatus.ACPresent, Type: Input, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.Charging, Type: Input, Value: 0.000000
Path: UPS.PowerSummary.PresentStatus.Discharging, Type: Input, Value: 0.000000
Path: UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit, Type: Input, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.FullyCharged, Type: Input, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.RemainingTimeLimitExpired, Type: Input, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.ACPresent, Type: Feature, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.Charging, Type: Feature, Value: 0.000000
Path: UPS.PowerSummary.PresentStatus.Discharging, Type: Feature, Value: 0.000000
Path: UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit, Type: Feature, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.FullyCharged, Type: Feature, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus.RemainingTimeLimitExpired, Type: Feature, Value: 1.000000
Path: UPS.PowerSummary.PresentStatus., Type: Input
Path: UPS.PowerSummary.PresentStatus., Type: Feature
Path: UPS.PowerSummary.AudibleAlarmControl, Type: Feature, Value: 2.000000
Path: UPS.PowerSummary.iManufacturer, Type: Feature, Value: 3.000000
Path: UPS.Input.ConfigVoltage, Type: Feature, Value: 120.000000
Path: UPS.Input.Voltage, Type: Feature, Value: 120.000000
Path: UPS.Input.LowVoltageTransfer, Type: Feature, Value: 90.000000
Path: UPS.Input.HighVoltageTransfer, Type: Feature, Value: 140.000000
Path: UPS.Output.Voltage, Type: Feature, Value: 120.000000
Path: UPS.Output.PercentLoad, Type: Feature, Value: 92.000000
Path: UPS.Output.Test, Type: Feature, Value: 1.000000
Path: UPS.Output.DelayBeforeShutdown, Type: Feature, Value: -1.000000
Path: UPS.Output.DelayBeforeStartup, Type: Feature, Value: 0.000000
Path: UPS.Output.Boost, Type: Feature, Value: 0.000000
Path: UPS.Output.Overload, Type: Feature, Value: 0.000000
Path: UPS.Output., Type: Feature
Path: UPS.Output.ConfigActivePower, Type: Feature, Value: 450.000000
Can't find object UPS.Battery.ConfigVoltage
Can't find object UPS.Battery.Temperature
Can't find object UPS.Battery.ManufacturerDate
Can't find object UPS.PowerSummary.APCBattReplaceDate
Can't find object UPS.Battery.APCBattReplaceDate
Can't find object UPS.PowerSummary.DelayBeforeShutdown
Can't find object UPS.APCGeneralCollection.APCDelayBeforeShutdown
Can't find object UPS.Battery.Test
Can't find object UPS.ManufacturerDate
Can't find object UPS.PowerSummary.ManufacturerDate
Can't find object UPS.PowerSummary.PresentStatus.ShutdownImminent
Can't find object UPS.PowerSummary.PresentStatus.Overload
Can't find object UPS.PowerSummary.PresentStatus.NeedReplacement
Can't find object UPS.PowerSummary.PresentStatus.BatteryPresent
Can't find object UPS.PowerSummary.Charging
Can't find object UPS.PowerSummary.Discharging
Can't find object UPS.PowerSummary.ACPresent
Can't find object UPS.PowerSummary.BelowRemainingCapacityLimit
Can't find object UPS.PowerSummary.ShutdownImminent
Can't find object UPS.Output.ConfigVoltage
Can't find object UPS.BatterySystem.Battery.Test
Can't find object UPS.BatterySystem.Battery.Test
Can't find object UPS.BatterySystem.Battery.Test
Can't find object UPS.APCPanelTest
Can't find object UPS.APCPanelTest
Can't find object UPS.PowerSummary.APCPanelTest
Can't find object UPS.PowerSummary.APCPanelTest
Can't find object UPS.PowerSummary.DelayBeforeShutdown
Can't find object UPS.APCGeneralCollection.APCDelayBeforeShutdown
Can't find object UPS.PowerSummary.DelayBeforeStartup
Can't find object UPS.APCGeneralCollection.APCForceShutdown
Can't find object UPS.APCGeneralCollection.APCDelayBeforeShutdown
Can't find object UPS.PowerSummary.DelayBeforeShutdown
upsdrv_updateinfo...
dstate_init: sock /var/state/ups/newhidups-hiddev0 open on fd 5
upsdrv_updateinfo...
Waiting for notifications...
=>Got 7 HID Objects...
ups.status = online
ups.status = !chrg
ups.status = !dischrg
ups.status = lowbatt
ups.status = fullycharged
ups.status = timelimitexp
find_hid_info: unknown variable: UPS.PowerSummary.PresentStatus.
upsdrv_updateinfo...
Waiting for notifications...
=>Got 3 HID Objects...
battery.charge = 120
battery.runtime = 240
battery.runtime.low = 300
upsdrv_updateinfo...
Waiting for notifications...
(it then loops)
<<EOF>>
# pico drivers/dynex-hid.c
/* dynex-hid.c - subdriver to monitor dynex USB/HID devices with NUT
*
* Copyright (C)
* 2003 - 2005 Arnaud Quette <arnaud.quette at free.fr>
* 2005 - 2006 Peter Selinger <selinger at users.sourceforge.net>
*
* Note: this subdriver was initially generated as a "stub" by the
* path-to-subdriver script. It must be customized.
*
* 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 "dynex-hid.h"
#include "extstate.h" /* for ST_FLAG_STRING */
#include "dstate.h" /* for STAT_INSTCMD_HANDLED */
#include "main.h" /* for getval() */
#include "common.h"
#define DYNEX_HID_VERSION "dynex HID 0.1"
#define DYNEX_VENDORID 0x0764
/* --------------------------------------------------------------- */
/* Vendor-specific usage table */
/* --------------------------------------------------------------- */
/* DYNEX usage table */
static usage_lkp_t dynex_usage_lkp[] = {
{ "\0", 0x0 }
};
static usage_tables_t dynex_utab[] = {
dynex_usage_lkp,
hid_usage_lkp,
NULL,
};
/* --------------------------------------------------------------- */
/* HID2NUT lookup table */
/* --------------------------------------------------------------- */
static hid_info_t dynex_hid2nut[] = {
{ "unmapped.ups.powersummary.iproduct", 0, 0, "UPS.PowerSummary.iProduct", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.iserialnumber", 0, 0, "UPS.PowerSummary.iSerialNumber", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.idevicechemistry", 0, 0, "UPS.PowerSummary.iDeviceChemistry", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.ioeminformation", 0, 0, "UPS.PowerSummary.iOEMInformation", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.rechargeable", 0, 0, "UPS.PowerSummary.Rechargeable", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.capacitymode", 0, 0, "UPS.PowerSummary.CapacityMode", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.designcapacity", 0, 0, "UPS.PowerSummary.DesignCapacity", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.capacitygranularity1", 0, 0, "UPS.PowerSummary.CapacityGranularity1", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.capacitygranularity2", 0, 0, "UPS.PowerSummary.CapacityGranularity2", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.warningcapacitylimit", 0, 0, "UPS.PowerSummary.WarningCapacityLimit", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.remainingcapacitylimit", 0, 0, "UPS.PowerSummary.RemainingCapacityLimit", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.fullchargecapacity", 0, 0, "UPS.PowerSummary.FullChargeCapacity", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.remainingcapacity", 0, 0, "UPS.PowerSummary.RemainingCapacity", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.remainingcapacity", 0, 0, "UPS.PowerSummary.RemainingCapacity", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.runtimetoempty", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.runtimetoempty", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.remainingtimelimit", 0, 0, "UPS.PowerSummary.RemainingTimeLimit", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.remainingtimelimit", 0, 0, "UPS.PowerSummary.RemainingTimeLimit", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.configvoltage", 0, 0, "UPS.PowerSummary.ConfigVoltage", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.voltage", 0, 0, "UPS.PowerSummary.Voltage", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.acpresent", 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.charging", 0, 0, "UPS.PowerSummary.PresentStatus.Charging", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.discharging", 0, 0, "UPS.PowerSummary.PresentStatus.Discharging", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.belowremainingcapacitylimit", 0, 0, "UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.fullycharged", 0, 0, "UPS.PowerSummary.PresentStatus.FullyCharged", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.remainingtimelimitexpired", 0, 0, "UPS.PowerSummary.PresentStatus.RemainingTimeLimitExpired", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.acpresent", 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.charging", 0, 0, "UPS.PowerSummary.PresentStatus.Charging", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.discharging", 0, 0, "UPS.PowerSummary.PresentStatus.Discharging", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.belowremainingcapacitylimit", 0, 0, "UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.fullycharged", 0, 0, "UPS.PowerSummary.PresentStatus.FullyCharged", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.remainingtimelimitexpired", 0, 0, "UPS.PowerSummary.PresentStatus.RemainingTimeLimitExpired", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.", 0, 0, "UPS.PowerSummary.PresentStatus.", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.presentstatus.", 0, 0, "UPS.PowerSummary.PresentStatus.", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.audiblealarmcontrol", 0, 0, "UPS.PowerSummary.AudibleAlarmControl", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.powersummary.imanufacturer", 0, 0, "UPS.PowerSummary.iManufacturer", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.input.configvoltage", 0, 0, "UPS.Input.ConfigVoltage", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.input.voltage", 0, 0, "UPS.Input.Voltage", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.input.lowvoltagetransfer", 0, 0, "UPS.Input.LowVoltageTransfer", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.input.highvoltagetransfer", 0, 0, "UPS.Input.HighVoltageTransfer", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.voltage", 0, 0, "UPS.Output.Voltage", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.percentload", 0, 0, "UPS.Output.PercentLoad", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.test", 0, 0, "UPS.Output.Test", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.delaybeforeshutdown", 0, 0, "UPS.Output.DelayBeforeShutdown", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.delaybeforestartup", 0, 0, "UPS.Output.DelayBeforeStartup", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.boost", 0, 0, "UPS.Output.Boost", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.overload", 0, 0, "UPS.Output.Overload", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.", 0, 0, "UPS.Output.", NULL, "%.0f", HU_FLAG_OK, NULL },
{ "unmapped.ups.output.configactivepower", 0, 0, "UPS.Output.ConfigActivePower", NULL, "%.0f", HU_FLAG_OK, NULL },
/* end of structure. */
{ NULL, 0, 0, NULL, NULL, NULL, 0, NULL }
};
/* shutdown method for dynex */
static int dynex_shutdown(int ondelay, int offdelay) {
/* FIXME: ondelay, offdelay currently not used */
/* Default method */
upsdebugx(2, "Trying load.off.");
if (instcmd("load.off", NULL) == STAT_INSTCMD_HANDLED) {
return 1;
}
upsdebugx(2, "Shutdown failed.");
return 0;
}
static char *dynex_format_model(HIDDevice *hd) {
return hd->Product;
}
static char *dynex_format_mfr(HIDDevice *hd) {
return hd->Vendor ? hd->Vendor : "dynex";
}
static char *dynex_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 dynex_claim(HIDDevice *hd) {
if (hd->VendorID != DYNEX_VENDORID) {
return 0;
}
switch (hd->ProductID) {
/* accept any known UPS - add devices here as needed */
case 0501:
return 1;
/* by default, reject, unless the productid option is given */
default:
if (getval("productid")) {
return 1;
} else {
upsdebugx(1,
"This particular dynex device (%04x/%04x) is not (or perhaps not yet)\n"
"supported by newhidups. Try running the driver with the '-x productid=%04x'\n"
"option. Please report your results to the NUT developer's mailing list.\n",
hd->VendorID, hd->ProductID, hd->ProductID);
return 0;
}
}
}
subdriver_t dynex_subdriver = {
DYNEX_HID_VERSION,
dynex_claim,
dynex_utab,
dynex_hid2nut,
dynex_shutdown,
dynex_format_model,
dynex_format_mfr,
dynex_format_serial,
};
<<EOF>>
# lsusb
Bus 005 Device 001: ID 0000:0000
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 003: ID 0764:0501 Cyber Power System, Inc.
Bus 001 Device 001: ID 0000:0000
<<EOF>>
I've tried running with the generic, cyberpower and cpsups drivers as well, but they failed to start. If I can provide any more info, please let me know.
Thank you,
Michael Hanson
More information about the Nut-upsuser
mailing list