Rob Groner
2014-Mar-06 20:55 UTC
[Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid)
My company is developing a new UPS, with smarts provided by a PIC32 Microchip micro-controller. The controller comes with a demo for a USBHID-UPS, and after some tweaking, I was able to get NUT to recognize it and start showing some reasonable values. To make this UPS as easy to use as possible for the end-user who chooses Linux, I figured I would just completely implement the official USB HID UPS spec. That way no subdriver would be needed, or at least very little. However, I am having a terrible time making sense of the pages in the NUT guide for writing USB HID drivers, and the USB HID usage table at usb.org. Just looking at some of the report ID values that I KNOW are working from the UPS example running on the microchip, I can't seem to find their equivalent in either doc. For instance, I know that the UPS code is sending status info using a Report ID of 0x40 and two bytes of data...but I cannot find anything in the usb.org docs that relates to this. NUT somehow understands it, though, since it correctly reports the device's status. Can someone point me to a reference to make sense of the doc, or some hints to help me interpret what I'm seeing? Thanks Rob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20140306/f3717966/attachment.html>
Tim Dawson
2014-Mar-06 21:35 UTC
[Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid)
Rob - Just out of curiosity, will this device also have any network monitoring connectivity, or just USB? Not sure what market you are targeting, but even as a small business/home compute user, I find that the distance limitations of USB often cause me grief, and myself, I would love to see a network alternative as well . . . Perhaps support for a network dongle on the USB port? More software, I know, but depending on what's embedded in your UPS, it does eliminate the need for a hardware-centric network implementation . . . - Tim On 03/06/2014 02:55 PM, Rob Groner wrote:> My company is developing a new UPS, with smarts provided by a PIC32 > Microchip micro-controller. The controller comes with a demo for a > USBHID-UPS, and after some tweaking, I was able to get NUT to recognize > it and start showing some reasonable values. > > To make this UPS as easy to use as possible for the end-user who chooses > Linux, I figured I would just completely implement the official USB HID > UPS spec. That way no subdriver would be needed, or at least very > little. However, I am having a terrible time making sense of the pages > in the NUT guide for writing USB HID drivers, and the USB HID usage > table at usb.org. Just looking at some of the report ID values that I > KNOW are working from the UPS example running on the microchip, I can?t > seem to find their equivalent in either doc. For instance, I know that > the UPS code is sending status info using a Report ID of 0x40 and two > bytes of data?but I cannot find anything in the usb.org docs that > relates to this. NUT somehow understands it, though, since it correctly > reports the device?s status. > > Can someone point me to a reference to make sense of the doc, or some > hints to help me interpret what I?m seeing? > > Thanks > > Rob > > > > _______________________________________________ > Nut-upsdev mailing list > Nut-upsdev at lists.alioth.debian.org > http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev >-- ===============================================================================Tim Dawson (tadawson at tpcsvc.com) Owner/Engineer TPC Services Bellnet: (972)-221-7385 Lewisville, Texas 75067 "Gaff Tape can't fix 'Stupid', but it can muffle the sound..."
Rob Groner
2014-Mar-06 22:08 UTC
[Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid)
Tim, The UPS will be a PC104 device (www.rtd.com to give you a quick visual of what that is), which means it will actually be physically stacked together with the power supply it is supporting. So cable length won't be an issue, as it will be communicating through USB in the PCIe bus to the CPU. Rob -----Original Message----- From: Nut-upsdev [mailto:nut-upsdev-bounces+rgroner=rtd.com at lists.alioth.debian.org] On Behalf Of Tim Dawson Sent: Thursday, March 06, 2014 4:35 PM To: nut-upsdev at lists.alioth.debian.org Subject: Re: [Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid) Rob - Just out of curiosity, will this device also have any network monitoring connectivity, or just USB? Not sure what market you are targeting, but even as a small business/home compute user, I find that the distance limitations of USB often cause me grief, and myself, I would love to see a network alternative as well . . . Perhaps support for a network dongle on the USB port? More software, I know, but depending on what's embedded in your UPS, it does eliminate the need for a hardware-centric network implementation . . . - Tim
Charles Lepple
2014-Mar-07 04:01 UTC
[Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid)
On Mar 6, 2014, at 3:55 PM, Rob Groner wrote:> To make this UPS as easy to use as possible for the end-user who chooses Linux, I figured I would just completely implement the official USB HID UPS spec. That way no subdriver would be needed, or at least very little.At the moment, we use USB VID and PID to select which HID-to-NUT tables to consult (since some vendors have "custom" (incorrect) interpretations of standard HID PDC Usages. So at the very least, you would need a skeleton usbhid-ups subdriver which matches your VID:PID combination. From there, though, if you follow the standard HID PDC Usage IDs, you should be able to just map the "HID path" (see below) to the corresponding NUT name.> However, I am having a terrible time making sense of the pages in the NUT guide for writing USB HID drivers, and the USB HID usage table at usb.org. Just looking at some of the report ID values that I KNOW are working from the UPS example running on the microchip, I can?t seem to find their equivalent in either doc. For instance, I know that the UPS code is sending status info using a Report ID of 0x40 and two bytes of data?but I cannot find anything in the usb.org docs that relates to this. NUT somehow understands it, though, since it correctly reports the device?s status.The report IDs aren't standardized - the HID Usage IDs are. The Report ID is essentially an opaque, small number to avoid having to send a full list of HID Usage IDs every time a new report is ready. If you look up Report ID 0x40 in your HID Report Descriptor, you should see a few HID Usage Pages and HID Usage IDs. Usage Pages are just the upper 16 bits of a full Usage ID as seen in the drivers. In the HID Report Descriptor, the Usage Pages and Usages will most likely be represented as hexadecimal. At the end of drivers/libhid.c (hid_usage_lkp[]) is a set of tables that map names to 32-bit hex Usage Page/Usage pairs. Another slightly strange concept in NUT is the way that HID Collections are represented. Each collection has a Usage Page/Usage associated with it, and for an UPS, these generally start with Page 0x84 (UPS) or Page 0x85 (Battery). They are separated with dots, and the whole thing is termed a "HID path" or similar. Let's use "UPS.PowerConverter.Output.Voltage" from an MGE Evolution as an example. From lsusb -vvv (run as root; with the Linux kernel HID driver detached if applicable, and the NUT driver stopped): Report Descriptor: (length is 1300) ... Item(Global): Usage Page, data= [ 0x84 ] 132 Power Device Page Item(Local ): Usage, data= [ 0x04 ] 4 UPS Item(Main ): Collection, data= [ 0x00 ] 0 Physical ... Item(Local ): Usage, data= [ 0x16 ] 22 Power Converter Item(Main ): Collection, data= [ 0x00 ] 0 Physical ... Item(Local ): Usage, data= [ 0x1c ] 28 Output Item(Main ): Collection, data= [ 0x00 ] 0 Physical ... Item(Global): Report ID, data= [ 0x1c ] 28 ... Item(Local ): Usage, data= [ 0x30 ] 48 Voltage Moving backwards from Voltage, we see that the Report ID is 0x1c. By summing up the size of the features in that Report (the Report size is "sticky" in that it is only specified when it changes between fields), we can find the offset and size of the voltage field. (Sizes are in bits.) I'll let the usbhid-ups driver do the dirty work: 5.648610 Report[buf]: (10 bytes) => 1c 01 04 57 00 49 00 77 00 3b 5.648687 Path: UPS.PowerConverter.Output.Voltage, Type: Feature, ReportID: 0x1c, Offset: 48, Size: 16, Value: 119 So an offset of 48 (counting past the report ID 0x1c at the beginning of the buffer) is 48/8 = 6 bytes in, for a value of "77 00" (0x0077 since USB is little-endian), or 119. -- Charles Lepple clepple at gmail
Rob Groner
2014-Mar-07 16:24 UTC
[Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid)
Charles, Thank you so much for the information. I'm trying to digest it along with the other docs I have, the example code from Microchip, and a USB HID tutorial I found online. So, if I understand correctly.... When the device first connects, it sends a huge dump of data (which the usbhid driver shows when you use the debug option) which fully describes the data it is capable of sending. The usage id's, pages, etc use values from the USBHID spec, but the actual data can be defined as needed by the device (in terms of width and ranges), and then the device assigns an arbitrary (but I'm assuming unique) report ID to the description so that when it needs to send the data, it can do so simply with a Report ID and the described data. Am I getting close to the truth? Rob -----Original Message----- From: Charles Lepple [mailto:clepple at gmail.com] Sent: Thursday, March 06, 2014 11:02 PM To: Rob Groner Cc: nut-upsdev at lists.alioth.debian.org Subject: Re: [Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid) On Mar 6, 2014, at 3:55 PM, Rob Groner wrote:> To make this UPS as easy to use as possible for the end-user who chooses Linux, I figured I would just completely implement the official USB HID UPS spec. That way no subdriver would be needed, or at least very little.At the moment, we use USB VID and PID to select which HID-to-NUT tables to consult (since some vendors have "custom" (incorrect) interpretations of standard HID PDC Usages. So at the very least, you would need a skeleton usbhid-ups subdriver which matches your VID:PID combination.>From there, though, if you follow the standard HID PDC Usage IDs, you should be able to just map the "HID path" (see below) to the corresponding NUT name.> However, I am having a terrible time making sense of the pages in the NUT guide for writing USB HID drivers, and the USB HID usage table at usb.org. Just looking at some of the report ID values that I KNOW are working from the UPS example running on the microchip, I can't seem to find their equivalent in either doc. For instance, I know that the UPS code is sending status info using a Report ID of 0x40 and two bytes of data...but I cannot find anything in the usb.org docs that relates to this. NUT somehow understands it, though, since it correctly reports the device's status.The report IDs aren't standardized - the HID Usage IDs are. The Report ID is essentially an opaque, small number to avoid having to send a full list of HID Usage IDs every time a new report is ready. If you look up Report ID 0x40 in your HID Report Descriptor, you should see a few HID Usage Pages and HID Usage IDs. Usage Pages are just the upper 16 bits of a full Usage ID as seen in the drivers. In the HID Report Descriptor, the Usage Pages and Usages will most likely be represented as hexadecimal. At the end of drivers/libhid.c (hid_usage_lkp[]) is a set of tables that map names to 32-bit hex Usage Page/Usage pairs. Another slightly strange concept in NUT is the way that HID Collections are represented. Each collection has a Usage Page/Usage associated with it, and for an UPS, these generally start with Page 0x84 (UPS) or Page 0x85 (Battery). They are separated with dots, and the whole thing is termed a "HID path" or similar. Let's use "UPS.PowerConverter.Output.Voltage" from an MGE Evolution as an example.>From lsusb -vvv (run as root; with the Linux kernel HID driver detached if applicable, and the NUT driver stopped):Report Descriptor: (length is 1300) ... Item(Global): Usage Page, data= [ 0x84 ] 132 Power Device Page Item(Local ): Usage, data= [ 0x04 ] 4 UPS Item(Main ): Collection, data= [ 0x00 ] 0 Physical ... Item(Local ): Usage, data= [ 0x16 ] 22 Power Converter Item(Main ): Collection, data= [ 0x00 ] 0 Physical ... Item(Local ): Usage, data= [ 0x1c ] 28 Output Item(Main ): Collection, data= [ 0x00 ] 0 Physical ... Item(Global): Report ID, data= [ 0x1c ] 28 ... Item(Local ): Usage, data= [ 0x30 ] 48 Voltage Moving backwards from Voltage, we see that the Report ID is 0x1c. By summing up the size of the features in that Report (the Report size is "sticky" in that it is only specified when it changes between fields), we can find the offset and size of the voltage field. (Sizes are in bits.) I'll let the usbhid-ups driver do the dirty work: 5.648610 Report[buf]: (10 bytes) => 1c 01 04 57 00 49 00 77 00 3b 5.648687 Path: UPS.PowerConverter.Output.Voltage, Type: Feature, ReportID: 0x1c, Offset: 48, Size: 16, Value: 119 So an offset of 48 (counting past the report ID 0x1c at the beginning of the buffer) is 48/8 = 6 bytes in, for a value of "77 00" (0x0077 since USB is little-endian), or 119. -- Charles Lepple clepple at gmail
Arnaud Quette
2014-Mar-14 21:13 UTC
[Nut-upsdev] Developing the UPS side of the UPS-NUT equation (via usbhid)
That recalls me that I was thinking about a potential default fallback subdriver implementing UPS.PowerSummary. Since I can't find any tracked evidence, I've logged few details : https://github.com/networkupstools/nut/issues/112 Note that I haven't gone through the whole thread... Cheers, Arno -- (sent from my eeePad... please excuse my brevity) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20140314/a816d270/attachment.html>
Possibly Parallel Threads
- Developing the UPS side of the UPS-NUT equation (via usbhid)
- Developing the UPS side of the UPS-NUT equation (via usbhid)
- Developing the UPS side of the UPS-NUT equation (via usbhid)
- Developing the UPS side of the UPS-NUT equation (via usbhid)
- Developing the UPS side of the UPS-NUT equation (via usbhid)