Skip to content

USB UPS not supported by usbhid-ups, even explore subdriver reads it wrong. I've manually decoded input and feature reports and they fit. #3227

@arkanoid87

Description

@arkanoid87

Hi

I'm writing a dummy driver for NUT for unsupported UPS speaking USB HID. I managed to read and decode everything.
I think the result of the work is worth sharing to understand if usbhid-ups can be improved.

USB HID Report Description from hid-decode https://gitlab.freedesktop.org/libevdev/hid-tools

$ hid-decode /dev/hidraw0                                                                                                                                                     
# device 0:0                                                                                                                                                                                                                                  
# 0x05, 0x84,                    // Usage Page (Power Device)           0                                                                                                                                                                     
# 0x09, 0x04,                    // Usage (Vendor Usage 0x04)           2                                                                                                                                                                     
# 0xa1, 0x01,                    // Collection (Application)            4                                                                                                                                                                     
# 0x05, 0x84,                    //  Usage Page (Power Device)          6                                                                                                                                                                     
# 0x09, 0x24,                    //  Usage (Vendor Usage 0x24)          8                                                                                                                                                                     
# 0xa1, 0x00,                    //  Collection (Physical)              10                                                                                                                                                                    
# 0x85, 0x0b,                    //   Report ID (11)                    12                                                                                                                                                                    
# 0x09, 0x25,                    //   Usage (Vendor Usage 0x25)         14                                                                                                                                                                    
# 0x09, 0x1f,                    //   Usage (Vendor Usage 0x1f)         16                                                                                                                                                                    
# 0x75, 0x04,                    //   Report Size (4)                   18                                                                                                                                                                    
# 0x95, 0x02,                    //   Report Count (2)                  20                                                                                                                                                                    
# 0x15, 0x00,                    //   Logical Minimum (0)               22                                                                                                                                                                    
# 0x25, 0x0f,                    //   Logical Maximum (15)              24                                                                                                                                                                    
# 0x65, 0x00,                    //   Unit (None)                       26                                                                                                                                                                    
# 0xb1, 0x03,                    //   Feature (Cnst,Var,Abs)            28                                                              
# 0x05, 0x85,                    //   Usage Page (Battery System)       30                                                              
# 0x09, 0xd1,                    //   Usage (Vendor Usage 0xd1)         32                                                              
# 0x09, 0x2c,                    //   Usage (Vendor Usage 0x2c)         34                                                              
# 0x09, 0x8b,                    //   Usage (Vendor Usage 0x8b)         36                                                                                    
# 0x75, 0x01,                    //   Report Size (1)                   38                                                                                    
# 0x95, 0x03,                    //   Report Count (3)                  40                                                                                    
# 0x25, 0x01,                    //   Logical Maximum (1)               42                                                                                    
# 0xb1, 0x03,                    //   Feature (Cnst,Var,Abs)            44                                                                                    
# 0x95, 0x05,                    //   Report Count (5)                  46                                                                                    
# 0xb1, 0x03,                    //   Feature (Cnst,Var,Abs)            48                                                                                    
# 0x05, 0x85,                    //   Usage Page (Battery System)       50                                                                                                                    
# 0x09, 0x83,                    //   Usage (Vendor Usage 0x83)         52                                                                                                                    
# 0x09, 0x8c,                    //   Usage (Vendor Usage 0x8c)         54                                                                                                                    
# 0x09, 0x8d,                    //   Usage (Vendor Usage 0x8d)         56                                                                                                                    
# 0x09, 0x8e,                    //   Usage (Vendor Usage 0x8e)         58                                                                                                                    
# 0x75, 0x18,                    //   Report Size (24)                  60                                                                                                                    
# 0x95, 0x04,                    //   Report Count (4)                  62                                                                                                                    
# 0x67, 0x01, 0x10, 0x10, 0x00,  //   Unit (SILinear: s * A)            64                                                                                                                    
# 0x55, 0x00,                    //   Unit Exponent (0)                 69 
# 0x27, 0xfe, 0xff, 0xff, 0x00,  //   Logical Maximum (16777214)        71 
# 0xb1, 0x03,                    //   Feature (Cnst,Var,Abs)            76 
# 0x05, 0x84,                    //   Usage Page (Power Device)         78 
# 0x09, 0x40,                    //   Usage (Vendor Usage 0x40)         80 
# 0x75, 0x10,                    //   Report Size (16)                  82 
# 0x95, 0x01,                    //   Report Count (1)                  84 
# 0x67, 0x21, 0xd1, 0xf0, 0x00,  //   Unit (SILinear: cm² * g * s⁻³ * A⁻¹) 86
# 0x55, 0x05,                    //   Unit Exponent (5)                 91 
# 0x27, 0xfe, 0xff, 0x00, 0x00,  //   Logical Maximum (65534)           93 
# 0xb1, 0x03,                    //   Feature (Cnst,Var,Abs)            98
# 0x05, 0x85,                    //   Usage Page (Battery System)       100
# 0x09, 0x67,                    //   Usage (Vendor Usage 0x67)         102
# 0x75, 0x18,                    //   Report Size (24)                  104
# 0x95, 0x01,                    //   Report Count (1)                  106
# 0x67, 0x01, 0x10, 0x10, 0x00,  //   Unit (SILinear: s * A)            108
# 0x55, 0x00,                    //   Unit Exponent (0)                 113
# 0x27, 0xfe, 0xff, 0xff, 0x00,  //   Logical Maximum (16777214)        115
# 0xb1, 0x83,                    //   Feature (Cnst,Var,Abs,Vol)        120
# 0x09, 0x66,                    //   Usage (Vendor Usage 0x66)         122
# 0x95, 0x01,                    //   Report Count (1)                  124
# 0xb1, 0x82,                    //   Feature (Data,Var,Abs,Vol)        126
# 0x09, 0x66,                    //   Usage (Vendor Usage 0x66)         128
# 0x95, 0x01,                    //   Report Count (1)                  130
# 0x81, 0x82,                    //   Input (Data,Var,Abs,Vol)          132
# 0x09, 0x68,                    //   Usage (Vendor Usage 0x68)         134
# 0x75, 0x10,                    //   Report Size (16)                  136
# 0x95, 0x01,                    //   Report Count (1)                  138
# 0x66, 0x01, 0x10,              //   Unit (SILinear: s)                140
# 0x55, 0x00,                    //   Unit Exponent (0)                 143
# 0x27, 0xfe, 0xff, 0x00, 0x00,  //   Logical Maximum (65534)           145
# 0x81, 0x83,                    //   Input (Cnst,Var,Abs,Vol)          150
# 0x05, 0x84,                    //   Usage Page (Power Device)         152
# 0x09, 0x02,                    //   Usage (Vendor Usage 0x02)         154
# 0xa1, 0x02,                    //   Collection (Logical)              156
# 0x05, 0x85,                    //    Usage Page (Battery System)      158
# 0x09, 0xd0,                    //    Usage (Vendor Usage 0xd0)        160
# 0x09, 0x45,                    //    Usage (Vendor Usage 0x45)        162
# 0x09, 0x44,                    //    Usage (Vendor Usage 0x44)        164
# 0x09, 0x42,                    //    Usage (Vendor Usage 0x42)        166
# 0x75, 0x01,                    //    Report Size (1)                  168
# 0x95, 0x04,                    //    Report Count (4)                 170
# 0x25, 0x01,                    //    Logical Maximum (1)              172
# 0x81, 0x83,                    //    Input (Cnst,Var,Abs,Vol)         174
# 0x95, 0x04,                    //    Report Count (4)                 176
# 0x81, 0x83,                    //    Input (Cnst,Var,Abs,Vol)         178
# 0xc0,                          //   End Collection                    180
# 0xc0,                          //  End Collection                     181
# 0xc0,                          // End Collection                      182
#                                                                                                                      
R: 183 05 84 09 04 a1 01 05 84 09 24 a1 00 85 0b 09 25 09 1f 75 04 95 02 15 00 25 0f 65 00 b1 03 05 85 09 d1 09 2c 09 8b 75 01 95 03 25 01 b1 03 95 05 b1 03 05 85 09 83 09 8c 09 8d 09 8e 75 18 95 04 67 01 10 10 00 55 00 27 fe ff ff 00 b1 03 05 84 09 40 75 10 95 01 67 21 d1 f0 00 55 05 27 fe ff 00 00 b1 03 05 85 09 67 75 18 95 01 67 01 10 10 00 55 00 27 fe ff ff 00 b1 83 09 66 95 01 b1 82 09 66 95 01 81 82 09 68 75 10 95 01 66 01 10 55 00 27 fe ff 00 00 81 83 05 84 09 02 a
1 02 05 85 09 d0 09 45 09 44 09 42 75 01 95 04 25 01 81 83 95 04 81 83 c0 c0 c0                                        
N: device 0:0                                                                                                          
I: 3 0001 0001

Output for fully charged UPS connected to mains

Input report 0x0b via hidapi-libusb or usbhid-dump -d 5131:2007 -e stream

0b900100000001

Feature report 0x0b via hidapi-libusb

0B3105900100280000040000010000DC00900100900100

usbhid-ups fails to decode fields correctly. I see 2 problems here:

  1. seems unable to separate input with feature values in mixed report description
  2. possibly reading the bit endianess wrong, but unsure as point 1 is the elephant in the room
$ ./usbhid-ups -DDDDDDD -s ups1 -x port=auto -x vendorid=5131 -x productid=2007 -x subdriver=explore -x pollonly -x pollinterval=2
   0.000001	[D3] main_arg: var='port' val='auto'
   0.000118	[D6] testinfo_reloadable: var=port, infoname=driver.parameter.port, newval=auto, reloadable=0, reload_flag=0
   0.000151	[D6] testinfo_reloadable: verdict for (re)loading var=port value: 1
   0.000194	[D5] send_to_all: SETINFO driver.parameter.port "auto"
   0.000226	[D3] main_arg: var='vendorid' val='5131'
   0.000272	[D5] send_to_all: SETINFO driver.parameter.vendorid "5131"
   0.000301	[D3] main_arg: var='productid' val='2007'
   0.000343	[D5] send_to_all: SETINFO driver.parameter.productid "2007"
   0.000369	[D3] main_arg: var='subdriver' val='explore'
   0.000409	[D5] send_to_all: SETINFO driver.parameter.subdriver "explore"
   0.000435	[D3] main_arg: var='pollonly' val='<null>'
   0.000471	[D5] send_to_all: SETINFO driver.flag.pollonly "enabled"
   0.000498	[D3] main_arg: var='pollinterval' val='2'
   0.000532	[D6] testval_reloadable: var=pollinterval, oldval=2, newval=2, reloadable=1, reload_flag=0
   0.000558	[D6] testval_reloadable: verdict for (re)loading var=pollinterval value: -1
   0.000577	[D1] Network UPS Tools version 2.8.1 (release/snapshot of 2.8.1) built with gcc (Raspbian 14.2.0-19+rpi1) 14.2.0 and configured with flags: --build=arm-linux-gnueabihf --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-option-checking --disable-silent-rules --libdir=${prefix}/lib/arm-linux-gnueabihf --runstatedir=/run --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --sysconfdir=/etc/nut --includedir=/usr/include --mandir=/usr/share/man --libdir=${prefix}/lib/arm-linux-gnueabihf --libexecdir=/usr/libexec --with-ssl --with-nss --with-cgi --with-dev --enable-static --with-statepath=/run/nut --with-altpidpath=/run/nut --with-drvpath=/usr/lib/nut --with-cgipath=/usr/lib/cgi-bin/nut --with-htmlpath=/usr/share/nut/www --with-pidpath=/run/nut --datadir=/usr/share/nut --with-pkgconfig-dir=/usr/lib/arm-linux-gnueabihf/pkgconfig --with-user=nut --with-group=nut --with-udev-dir=/usr/lib/udev --with-systemdsystemunitdir=/usr/lib/systemd/system --with-systemdshutdowndir=/usr/lib/systemd/system-shutdown --with-systemdtmpfilesdir=/usr/lib/tmpfiles.d --with-python=python3 --with-python3=/usr/bin/python3 --with-doc=man
   0.000642	[D1] debug level is '7'
   0.000675	[D5] send_to_all: SETINFO driver.debug "7"
   0.000707	[D5] send_to_all: SETFLAGS driver.debug RW NUMBER
   0.001590	[D1] Can not become_user(nut): not root initially, remaining UID=1000 GID=1000
   0.001688	[D5] send_to_all: SETINFO device.type "ups"
   0.001726	[D5] send_to_all: SETINFO driver.state "init.device"
   0.001751	[D1] upsdrv_initups (non-SHUT)...
   0.001779	[D2] Initializing an USB-connected UPS with library libusb-1.0.28 (API: 0x100010a) (NUT subdriver name='USB communication driver (libusb 1.0)' ver='0.46')
   0.038649	[D2] Checking device 1 of 5 (5131/2007)
   0.038831	[D2] - VendorID: 5131
   0.038863	[D2] - ProductID: 2007
   0.038888	[D2] - Manufacturer: unknown
   0.038911	[D2] - Product: unknown
   0.038930	[D2] - Serial Number: unknown
   0.038950	[D2] - Bus: 001
   0.038970	[D2] - Bus Port: 005
   0.038989	[D2] - Device: 005
   0.039009	[D2] - Device release number: 0000
   0.039028	[D2] Trying to match device
   0.039056	[D2] match_function_subdriver_name: matching a subdriver by explicit name/regex: 'explore'...
   0.039125	[D2] match_function_subdriver_name: retry matching by regex 'as is'
   0.039420	[D2] match_function_subdriver_name: retry matching by regex with added '.*'
   0.039600	[D2] match_function_subdriver_name: found a match: EXPLORE HID 0.2
   0.039640	[D3] match_function_regex: matching a device...
   0.039772	[D2] Device matches
   0.039801	[D2] Reading first configuration descriptor
   0.039856	[D3] libusb_kernel_driver_active() returned 0: Success
   0.040055	[D2] Claimed interface 0 successfully
   0.040096	[D3] nut_usb_set_altinterface: skipped libusb_set_interface_alt_setting(udev, 0, 0)
   0.040670	[D2] Retrieved HID descriptor (expected 9, got 9)
   0.040730	[D3] HID descriptor, method 1: (9 bytes) => 0b 90 01 00 00 00 01 00 00
   0.040754	[D3] HID descriptor length (method 1) 0
   0.040778	[D4] i=0, extra[i]=09, extra[i+1]=21
   0.040817	[D3] HID descriptor, method 2: (9 bytes) => 09 21 11 01 00 01 22 b7 00
   0.040845	[D3] HID descriptor length (method 2) 183
   0.040867	[D2] Warning: two different HID descriptors retrieved (Reportlen = 0 vs. 183)
   0.040888	[D2] HID descriptor length 183
   0.045429	[D2] Report Descriptor size = 183
   0.045519	[D3] Report Descriptor: (183 bytes) => 05 84 09 04 a1 01 05 84 09 24 a1 00 85 0b
   0.045581	[D3]  09 25 09 1f 75 04 95 02 15 00 25 0f 65 00 b1 03 05 85 09 d1 09 2c 09 8b 75
   0.045656	[D3]  01 95 03 25 01 b1 03 95 05 b1 03 05 85 09 83 09 8c 09 8d 09 8e 75 18 95 04
   0.045715	[D3]  67 01 10 10 00 55 00 27 fe ff ff 00 b1 03 05 84 09 40 75 10 95 01 67 21 d1
   0.045780	[D3]  f0 00 55 05 27 fe ff 00 00 b1 03 05 85 09 67 75 18 95 01 67 01 10 10 00 55
   0.045838	[D3]  00 27 fe ff ff 00 b1 83 09 66 95 01 b1 82 09 66 95 01 81 82 09 68 75 10 95
   0.045899	[D3]  01 66 01 10 55 00 27 fe ff 00 00 81 83 05 84 09 02 a1 02 05 85 09 d0 09 45
   0.045948	[D3]  09 44 09 42 75 01 95 04 25 01 81 83 95 04 81 83 c0 c0 c0
   0.046157	[D2] match_function_subdriver_name: matching a subdriver by explicit name/regex: 'explore'...
   0.046198	[D2] match_function_subdriver_name: retry matching by regex 'as is'
   0.046436	[D2] match_function_subdriver_name: retry matching by regex with added '.*'
   0.046610	[D2] match_function_subdriver_name: found a match: EXPLORE HID 0.2
   0.046645	Using subdriver: EXPLORE HID 0.2
   0.046669	[D1] 18 HID objects found
   0.046694	[D4] Entering libusb_get_report
   0.047296	[D3] Report[get]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.047342	[D3]  00 90 01 00 90 01 00
   0.047370	[D5] PhyMax = 0, PhyMin = 0, LogMax = 15, LogMin = 0
   0.047393	[D5] Unit = 00000000, UnitExp = 0
   0.047413	[D5] Exponent = 0
   0.047437	[D5] hid_lookup_path: 00840004 -> UPS
   0.047464	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.047490	[D5] hid_lookup_path: 00840025 -> PowerSummaryID
   0.047523	[D1] Path: UPS.PowerSummary.PowerSummaryID, Type: Feature, ReportID: 0x0b, Offset: 0, Size: 4, Value: 1
   0.047624	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.047667	[D3]  00 90 01 00 90 01 00
   0.047692	[D5] PhyMax = 0, PhyMin = 0, LogMax = 15, LogMin = 0
   0.047714	[D5] Unit = 00000000, UnitExp = 0
   0.047735	[D5] Exponent = 0
   0.047758	[D5] hid_lookup_path: 00840004 -> UPS
   0.047809	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.047836	[D5] hid_lookup_path: 0084001f -> FlowID
   0.047866	[D1] Path: UPS.PowerSummary.FlowID, Type: Feature, ReportID: 0x0b, Offset: 4, Size: 4, Value: 3
   0.047914	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.047949	[D3]  00 90 01 00 90 01 00
   0.047972	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.047995	[D5] Unit = 00000000, UnitExp = 0
   0.048015	[D5] Exponent = 0
   0.048036	[D5] hid_lookup_path: 00840004 -> UPS
   0.048060	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.048087	[D5] hid_lookup_path: 008500d1 -> BatteryPresent
   0.048116	[D1] Path: UPS.PowerSummary.BatteryPresent, Type: Feature, ReportID: 0x0b, Offset: 8, Size: 1, Value: 1
   0.048164	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.048196	[D3]  00 90 01 00 90 01 00
   0.048219	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.048242	[D5] Unit = 00000000, UnitExp = 0
   0.048263	[D5] Exponent = 0
   0.048285	[D5] hid_lookup_path: 00840004 -> UPS
   0.048309	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.048335	[D5] hid_lookup_path: 0085002c -> CapacityMode
   0.048365	[D1] Path: UPS.PowerSummary.CapacityMode, Type: Feature, ReportID: 0x0b, Offset: 9, Size: 1, Value: 0
   0.048413	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.048447	[D3]  00 90 01 00 90 01 00
   0.048470	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.048492	[D5] Unit = 00000000, UnitExp = 0
   0.048513	[D5] Exponent = 0
   0.048535	[D5] hid_lookup_path: 00840004 -> UPS
   0.048560	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.048604	[D5] hid_lookup_path: 0085008b -> Rechargeable
   0.048635	[D1] Path: UPS.PowerSummary.Rechargeable, Type: Feature, ReportID: 0x0b, Offset: 10, Size: 1, Value: 1
   0.048683	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.048716	[D3]  00 90 01 00 90 01 00
   0.048740	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.048763	[D5] Unit = 00101001, UnitExp = 0
   0.048783	[D5] Exponent = 0
   0.048804	[D5] hid_lookup_path: 00840004 -> UPS
   0.048829	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.048856	[D5] hid_lookup_path: 00850083 -> DesignCapacity
   0.048893	[D1] Path: UPS.PowerSummary.DesignCapacity, Type: Feature, ReportID: 0x0b, Offset: 16, Size: 24, Value: 400
   0.048983	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.049022	[D3]  00 90 01 00 90 01 00
   0.049048	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.049071	[D5] Unit = 00101001, UnitExp = 0
   0.049091	[D5] Exponent = 0
   0.049114	[D5] hid_lookup_path: 00840004 -> UPS
   0.049138	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.049164	[D5] hid_lookup_path: 0085008c -> WarningCapacityLimit
   0.049197	[D1] Path: UPS.PowerSummary.WarningCapacityLimit, Type: Feature, ReportID: 0x0b, Offset: 40, Size: 24, Value: 40
   0.049247	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.049281	[D3]  00 90 01 00 90 01 00
   0.049305	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.049327	[D5] Unit = 00101001, UnitExp = 0
   0.049348	[D5] Exponent = 0
   0.049369	[D5] hid_lookup_path: 00840004 -> UPS
   0.049394	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.049419	[D5] hid_lookup_path: 0085008d -> CapacityGranularity1
   0.049449	[D1] Path: UPS.PowerSummary.CapacityGranularity1, Type: Feature, ReportID: 0x0b, Offset: 64, Size: 24, Value: 4
   0.049497	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.049531	[D3]  00 90 01 00 90 01 00
   0.049555	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.049578	[D5] Unit = 00101001, UnitExp = 0
   0.049598	[D5] Exponent = 0
   0.049620	[D5] hid_lookup_path: 00840004 -> UPS
   0.049644	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.049670	[D5] hid_lookup_path: 0085008e -> CapacityGranularity2
   0.049700	[D1] Path: UPS.PowerSummary.CapacityGranularity2, Type: Feature, ReportID: 0x0b, Offset: 88, Size: 24, Value: 1
   0.049749	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.049798	[D3]  00 90 01 00 90 01 00
   0.049822	[D5] PhyMax = 0, PhyMin = 0, LogMax = 65534, LogMin = 0
   0.049844	[D5] Unit = 00f0d121, UnitExp = 5
   0.049864	[D5] Exponent = -2
   0.049886	[D5] hid_lookup_path: 00840004 -> UPS
   0.049937	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.049963	[D5] hid_lookup_path: 00840040 -> ConfigVoltage
   0.049992	[D1] Path: UPS.PowerSummary.ConfigVoltage, Type: Feature, ReportID: 0x0b, Offset: 112, Size: 16, Value: 2.2
   0.050041	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.050075	[D3]  00 90 01 00 90 01 00
   0.050099	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.050122	[D5] Unit = 00101001, UnitExp = 0
   0.050142	[D5] Exponent = 0
   0.050164	[D5] hid_lookup_path: 00840004 -> UPS
   0.050188	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.050214	[D5] hid_lookup_path: 00850067 -> FullChargeCapacity
   0.050246	[D1] Path: UPS.PowerSummary.FullChargeCapacity, Type: Feature, ReportID: 0x0b, Offset: 128, Size: 24, Value: 400
   0.050295	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.050329	[D3]  00 90 01 00 90 01 00
   0.050354	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.050376	[D5] Unit = 00101001, UnitExp = 0
   0.050396	[D5] Exponent = 0
   0.050417	[D5] hid_lookup_path: 00840004 -> UPS
   0.050442	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.050468	[D5] hid_lookup_path: 00850066 -> RemainingCapacity
   0.050499	[D1] Path: UPS.PowerSummary.RemainingCapacity, Type: Feature, ReportID: 0x0b, Offset: 152, Size: 24, Value: 400
   0.050548	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.050582	[D3]  00 90 01 00 90 01 00
   0.050606	[D5] PhyMax = 0, PhyMin = 0, LogMax = 16777214, LogMin = 0
   0.050628	[D5] Unit = 00101001, UnitExp = 0
   0.050648	[D5] Exponent = 0
   0.050670	[D5] hid_lookup_path: 00840004 -> UPS
   0.050694	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.050720	[D5] hid_lookup_path: 00850066 -> RemainingCapacity
   0.050756	[D1] Path: UPS.PowerSummary.RemainingCapacity, Type: Input, ReportID: 0x0b, Offset: 0, Size: 24, Value: 9.43851e+06
   0.050823	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.050855	[D3]  00 90 01 00 90 01 00
   0.050878	[D5] PhyMax = 0, PhyMin = 0, LogMax = 65534, LogMin = 0
   0.050901	[D5] Unit = 00001001, UnitExp = 0
   0.050922	[D5] Exponent = 0
   0.050944	[D5] hid_lookup_path: 00840004 -> UPS
   0.050971	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.050997	[D5] hid_lookup_path: 00850068 -> RunTimeToEmpty
   0.051026	[D1] Path: UPS.PowerSummary.RunTimeToEmpty, Type: Input, ReportID: 0x0b, Offset: 24, Size: 16, Value: 1
   0.051075	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.051109	[D3]  00 90 01 00 90 01 00
   0.051133	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.051155	[D5] Unit = 00001001, UnitExp = 0
   0.051175	[D5] Exponent = 0
   0.051198	[D5] hid_lookup_path: 00840004 -> UPS
   0.051242	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.051268	[D5] hid_lookup_path: 00840002 -> PresentStatus
   0.051295	[D5] hid_lookup_path: 008500d0 -> ACPresent
   0.051324	[D1] Path: UPS.PowerSummary.PresentStatus.ACPresent, Type: Input, ReportID: 0x0b, Offset: 40, Size: 1, Value: 0
   0.051372	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.051407	[D3]  00 90 01 00 90 01 00
   0.051430	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.051452	[D5] Unit = 00001001, UnitExp = 0
   0.051472	[D5] Exponent = 0
   0.051494	[D5] hid_lookup_path: 00840004 -> UPS
   0.051519	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.051543	[D5] hid_lookup_path: 00840002 -> PresentStatus
   0.051569	[D5] hid_lookup_path: 00850045 -> Discharging
   0.051598	[D1] Path: UPS.PowerSummary.PresentStatus.Discharging, Type: Input, ReportID: 0x0b, Offset: 41, Size: 1, Value: 0
   0.051683	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.051722	[D3]  00 90 01 00 90 01 00
   0.051747	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.051769	[D5] Unit = 00001001, UnitExp = 0
   0.051789	[D5] Exponent = 0
   0.051811	[D5] hid_lookup_path: 00840004 -> UPS
   0.051836	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.051937	[D5] hid_lookup_path: 00840002 -> PresentStatus
   0.051968	[D5] hid_lookup_path: 00850044 -> Charging
   0.051999	[D1] Path: UPS.PowerSummary.PresentStatus.Charging, Type: Input, ReportID: 0x0b, Offset: 42, Size: 1, Value: 0
   0.052075	[D3] Report[buf]: (23 bytes) => 0b 31 05 90 01 00 28 00 00 04 00 00 01 00 00 dc
   0.052108	[D3]  00 90 01 00 90 01 00
   0.052131	[D5] PhyMax = 0, PhyMin = 0, LogMax = 1, LogMin = 0
   0.052153	[D5] Unit = 00001001, UnitExp = 0
   0.052175	[D5] Exponent = 0
   0.052197	[D5] hid_lookup_path: 00840004 -> UPS
   0.052243	[D5] hid_lookup_path: 00840024 -> PowerSummary
   0.052269	[D5] hid_lookup_path: 00840002 -> PresentStatus
   0.052295	[D5] hid_lookup_path: 00850042 -> BelowRemainingCapacityLimit
   0.052325	[D1] Path: UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit, Type: Input, ReportID: 0x0b, Offset: 43, Size: 1, Value: 1
Network UPS Tools - Generic HID driver 0.52 (2.8.1)
USB communication driver (libusb 1.0) 0.46
   0.052382	[D5] send_to_all: SETINFO ups.vendorid "5131"
   0.052421	[D5] send_to_all: SETINFO ups.productid "2007"
   0.052445	[D2] Report descriptor retrieved (Reportlen = 183)
   0.052465	[D2] Found HID device
   0.052492	[D1] Detected a UPS: unknown/unknown
   0.052532	[D2] find_nut_info: unknown info type: load.off.delay
   0.052569	[D2] find_nut_info: unknown info type: load.on.delay
   0.052591	[D2] find_nut_info: unknown info type: load.off.delay
   0.052623	[D5] send_to_all: SETINFO driver.state "init.quiet"
   0.052660	[D5] send_to_all: SETINFO driver.version "2.8.1"
   0.052692	[D5] send_to_all: SETINFO driver.version.internal "0.52"
   0.052725	[D5] send_to_all: SETINFO driver.name "usbhid-ups"
   0.052755	[D5] send_to_all: SETINFO driver.state "init.info"
   0.052777	[D1] upsdrv_initinfo...
   0.052810	[D5] send_to_all: SETINFO driver.version.data "EXPLORE HID 0.2"
   0.052869	[D5] send_to_all: SETINFO driver.parameter.pollfreq "30"
   0.052902	[D5] send_to_all: SETINFO driver.state "init.updateinfo"
   0.052946	[D1] upsdrv_updateinfo...
   0.052968	[D1] Not using interrupt pipe...
   0.052992	[D1] Quick update...
   0.053027	[D5] send_to_all: SETINFO ups.status "OB"
   0.053063	[D5] send_to_all: DATAOK
   0.053094	[D5] send_to_all: SETINFO driver.state "init.quiet"
   0.053368	[D2] dstate_init: sock /run/nut/usbhid-ups-ups1 open on fd 9
   0.053425	[D5] send_to_all: SETINFO driver.parameter.pollinterval "2"
   0.053468	[D5] send_to_all: SETINFO driver.parameter.synchronous "auto"
   0.053511	Running as foreground process, not saving a PID file
   0.053545	[D5] send_to_all: SETINFO driver.flag.allow_killpower "0"
   0.053577	[D5] send_to_all: SETFLAGS driver.flag.allow_killpower RW NUMBER
   0.053605	[D5] send_to_all: ADDCMD driver.killpower
   0.053631	[D5] send_to_all: ADDCMD driver.reload
   0.053682	[D5] send_to_all: ADDCMD driver.reload-or-exit
   0.053709	[D5] send_to_all: ADDCMD driver.reload-or-error
   0.053738	[D5] send_to_all: SETINFO driver.state "quiet"
   0.053760	[D1] Driver initialization completed, beginning regular infinite loop
   0.053786	upsnotify: notify about state 2 with libsystemd: was requested, but not running as a service unit now, will not spam more about it
   0.053813	upsnotify: failed to notify about state 2: no notification tech defined, will not spam more about it
   0.053835	upsnotify: logged the systemd watchdog situation once, will not spam more about it
   0.053865	[D5] send_to_all: SETINFO driver.state "updateinfo"
   0.053908	[D1] upsdrv_updateinfo...
   0.053930	[D1] Not using interrupt pipe...
   0.053952	[D1] Quick update...
   0.053987	[D5] send_to_all: SETINFO driver.state "quiet"
   2.056042	[D5] send_to_all: SETINFO driver.state "updateinfo"
   2.056138	[D1] upsdrv_updateinfo...
   2.056173	[D1] Not using interrupt pipe...
   2.056207	[D1] Quick update...
   2.056259	[D5] send_to_all: SETINFO driver.state "quiet"
   4.058112	[D5] send_to_all: SETINFO driver.state "updateinfo"
   4.058183	[D1] upsdrv_updateinfo...
   4.058213	[D1] Not using interrupt pipe...
   4.058245	[D1] Quick update...
   4.058291	[D5] send_to_all: SETINFO driver.state "quiet"

you can see that UPS.PowerSummary.PresentStatus.ACPresent, Type: Input, ReportID: 0x0b, Offset: 40, Size: 1, Value: 0 which is wrong as the UPS is AC connected

My decoder is 1:1 with report description and decodes it correctly.
It is written in Nim programming language, but it proves the point.

struct(inputReport11, plugins = {converters}, endian = l, bitEndian = r):
  u8:
    reportId = 0x0B # Byte 0: Report ID (11)
  u24:
    ramainingCapacity # Bytes 1-3: Usage 0x66 (SI Units: s * A)
  u16:
    runTimeToEmpty # Bytes 4-5: Usage 0x68 (s)
  1:
    acPresent # Byte 6 bit 0: Usage 0xD0
  1:
    discharging # Byte 6 bit 1: Usage 0x45
  1:
    charging # Byte 6 bit 2: Usage 0x44
  1:
    belowRemainingCapacityLimit # Byte 6 bit 3: Usage 0x42
  4:
    _ # Byte 6 bits 4-7 + Bytes 7-8: Padding

struct(featureReport11, plugins = {converters}, endian = l, bitEndian = r):
  u8:
    reportId = 0x0B # Byte 0: Report ID (11)
  u4:
    powerSummaryId # Byte 1 low nibble: Usage 0x25
  u4:
    flowId # Byte 1 high nibble: Usage 0x1F
  1:
    batteryPresent # Byte 2 bit 0: Usage 0xD1
  1:
    capacityMode # Byte 2 bit 1: Usage 0x2C
  1:
    rechargeable # Byte 2 bit 2: Usage 0x8B
  5:
    padding # Byte 2 bits 3-7 + Bytes 3-4: Padding
  u24:
    designCapacity # Bytes 3-5: Usage 0x83 (SI Units: s * A)
  u24:
    warningCapacityLimit # Bytes 6-8: Usage 0x8C (SI Units: s * A)
  u24:
    capacityGranularity1 # Bytes 9-11: Usage 0x8D (SI Units: s * A)
  u24:
    capacityGranularity2 # Bytes 12-14: Usage 0x8E (SI Units: s * A)
  u16:
    configVoltage # Bytes 15-16: Usage 0x40 (SI Units: V * 10^5)
  u24:
    fullChargeCapacity # Bytes 17-19: Usage 0x67 (SI Units: s * A, Volatile)
  u24:
    ramainingCapacity # Bytes 20-22: Usage 0x66 (SI Units: s * A)

result for fully charged UPS connected to mains

hexInputData = 0b900100000001
parsedData = (reportId: 11, ramainingCapacity: 400, runTimeToEmpty: 0, acPresent: 1, discharging: 0, charging: 0, belowRemainingCapacityLimit: 0)
hexFeatureData = 0B3105900100280000040000010000DC00900100900100
parsedData = (reportId: 11, powerSummaryId: 1, flowId: 3, batteryPresent: 1, capacityMode: 0, rechargeable: 1, padding: 0, designCapacity: 400, warningCapacityLimit: 40, capacityGranularity1: 4, capacityGranularity2: 1, configVoltage: 220, fullChargeCapacity: 400, ramainingCapacity: 400)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Incorrect or missing readingsOn some devices driver-reported values are systemically off (e.g. x10, x0.1, const+Value, etc.)USB VID=0001 PID=0000 (Fry's Electronics/MEC0003)Seems to be a generic USB chip interfacing many devices and protocols (Qx, USB HID, ATCL...)impacts-release-2.8.1Issues reported against NUT release 2.8.1 (maybe vanilla or with minor packaging tweaks)raspberry

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions