networkupstools / nut

The Network UPS Tools repository. UPS management protocol Informational RFC 9271 published by IETF at https://www.rfc-editor.org/info/rfc9271 Please star NUT on GitHub, this helps with sponsorships!
https://networkupstools.org/
Other
1.99k stars 349 forks source link

nutdrv_qx multiple identical ups USB issue #1174

Open arisjr opened 2 years ago

arisjr commented 2 years ago

We have several 15 identical voltronic UPS's here and they came only with USB and Serial ports enabled. We are trying to implement the monitoring on RPi3's for every four nobreaks. For one ups it works fine, the problem is to connect more than one ups.

For a reason we don't know, all serial numbers returned from the UPS to the driver are "unkown", so we do not have a way to individualize the nobreaks on ups.conf.

In this scenario, with "port = auto", only the first USB port is accessed by the driver. Even if we had four ups configured on ups.conf, only the last loaded ups will work, because the driver only access the first device it sees.

Is there a way to make the driver more aware of the devices it already handles and only load the driver on unused devices? Or is there another form for me to individualize the UPS devices for it to load correctly multiple USB devices?

System Specs:

UPS: Voltronic Power, Model: WINNER PRO 3000VA Machine: Rpi3 System: ubuntu 20.04 server armhf raspi Nutdrv_qx (from APT): Network UPS Tools - Generic Q* USB/Serial driver 0.28 (2.7.4), USB communication driver 0.33

ups.conf example

[ups-port01] driver = nutdrv_qx port = auto desc = "Voltronic Power PORT01"

[ups-port02] driver = nutdrv_qx port = auto desc = "Voltronic Power PORT02"

Driver exit (I intentionally set a random serial number for it to list all devices)

$ sudo /usr/lib/nut/nutdrv_qx -a ups-port01 -DD Network UPS Tools - Generic Q* USB/Serial driver 0.28 (2.7.4) USB communication driver 0.33 0.000000 debug level is '2' 0.003595 upsdrv_initups... 0.004911 Checking device (0665/5161) (001/005) 1.373362 - VendorID: 0665 1.373487 - ProductID: 5161 1.373581 - Manufacturer: unknown 1.373670 - Product: unknown 1.373732 - Serial Number: unknown 1.373812 - Bus: 001 1.373873 - Device release number: 0002 1.373923 Trying to match device 1.374007 Device does not match - skipping 1.374115 Checking device (0665/5161) (001/004) 1.384912 - VendorID: 0665 1.385042 - ProductID: 5161 1.385169 - Manufacturer: INNO TECH 1.385266 - Product: USB to Serial 1.385346 - Serial Number: unknown 1.385425 - Bus: 001 1.385502 - Device release number: 0002 1.385580 Trying to match device 1.385686 Device does not match - skipping 1.385787 Checking device (0424/EC00) (001/003) 1.385964 - VendorID: 0424 1.386025 - ProductID: ec00 1.386072 - Manufacturer: unknown 1.386151 - Product: unknown 1.386205 - Serial Number: unknown 1.386243 - Bus: 001 1.386297 - Device release number: 0200 1.386359 Trying to match device 1.386415 Device does not match - skipping 1.386493 Checking device (0424/9514) (001/002) 1.386603 - VendorID: 0424 1.386659 - ProductID: 9514 1.386718 - Manufacturer: unknown 1.386771 - Product: unknown 1.386823 - Serial Number: unknown 1.386877 - Bus: 001 1.386921 - Device release number: 0200 1.386972 Trying to match device 1.387035 Device does not match - skipping 1.387111 Checking device (1D6B/0002) (001/001) 1.387235 - VendorID: 1d6b 1.387288 - ProductID: 0002 1.387346 - Manufacturer: unknown 1.387398 - Product: unknown 1.387451 - Serial Number: unknown 1.387500 - Bus: 001 1.387557 - Device release number: 0504 1.387608 Trying to match device 1.387669 Device does not match - skipping

lsusb (with two UPS connected on rpi)

$ lsusb -v -d 0665:

Bus 001 Device 005: ID 0665:5161 Cypress Semiconductor USB to Serial Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0665 Cypress Semiconductor idProduct 0x5161 USB to Serial bcdDevice 0.02 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0022 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 3 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 4 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.00 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 27 Report Descriptors: UNAVAILABLE Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 1

Bus 001 Device 004: ID 0665:5161 Cypress Semiconductor USB to Serial Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x0665 Cypress Semiconductor idProduct 0x5161 USB to Serial bcdDevice 0.02 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0022 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 3 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 4 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.00 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 27 Report Descriptors: UNAVAILABLE Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 1

jimklimov commented 2 years ago

I assume the NUT build "from APT" is based on the latest official release, which alas was a few years ago and we are polishing code to publish as 2.7.5. Until then, you can try chances with a manually made build from github sources on the master branch.

In recent months a number of fixes landed for improving USB support, maybe some of those would just help. I remember discussion of ways to differentiate devices that report identically but are connected to different ports; it might require that configuration specifies unique port pathnames however (not "auto").

arisjr commented 2 years ago

Thanks for the response, Jim.

I tried changing the port on the 2.7.4 version that is installed, that's the APT version for ubuntu 20.04.

Using HID On the 2.7.4 nut version, using nutdrv_qx driver, if I try "/dev/usb/hiddev0" or "/dev/hidraw0" on the port, it returns to me: "tcgetattr(/dev/usb/hiddev0): Invalid argument" and "tcgetattr(/dev/hidraw0): Invalid argument". What is the best hid device to use? Is there another thing I can do with hid?

Trying tty I tried blacklisting usbhid module and force ftdi_sio on the USB device to get the /dev/ttyUSB0, because it's a USB to Serial device, so I gave it a try. Although the port /dev/ttyUSB0 passes on the driver initial check, It returns Device not supported, I think maybe it's because nutdrv_qx uses hid for the voltronic UPS. I don't know. Can I try another generic driver on this UPS?

$ sudo /usr/lib/nut/nutdrv_qx -a ups-port01 -DD Network UPS Tools - Generic Q* USB/Serial driver 0.28 (2.7.4) USB communication driver 0.33 0.000000 debug level is '2' 0.003468 upsdrv_initups... 0.149452 qx_process_answer: short reply (input.voltage) 0.149600 qx_process_answer: short reply (input.voltage) 0.149707 qx_process_answer: short reply (input.voltage) 0.149807 qx_process_answer: short reply (ups.firmware.aux) 0.149913 qx_process_answer: short reply (ups.firmware.aux) 0.150087 qx_process_answer: short reply (ups.firmware.aux) 0.150240 qx_process_answer: short reply (ups.firmware.aux) 0.150452 qx_process_answer: short reply (ups.firmware.aux) 0.150601 qx_process_answer: short reply (ups.firmware.aux) 0.150872 qx_process_answer: short reply (input.voltage) 0.151022 qx_process_answer: short reply (input.voltage) 0.151231 qx_process_answer: short reply (input.voltage) 0.151327 qx_process_answer: short reply (input.voltage) 0.151446 qx_process_answer: short reply (input.voltage) 0.151541 qx_process_answer: short reply (input.voltage) 0.151664 qx_process_answer: short reply (input.voltage) 0.151757 qx_process_answer: short reply (input.voltage) 0.151863 qx_process_answer: short reply (input.voltage) 0.151957 qx_process_answer: short reply (input.voltage) 0.152060 qx_process_answer: short reply (input.voltage) 0.152155 qx_process_answer: short reply (input.voltage) 0.152260 qx_process_answer: short reply (input.voltage) 0.152363 qx_process_answer: short reply (input.voltage) 0.152467 qx_process_answer: short reply (input.voltage) 0.152571 qx_process_answer: short reply (input.voltage) 0.152676 qx_process_answer: short reply (input.voltage) 0.152769 qx_process_answer: short reply (input.voltage) 0.152874 qx_process_answer: short reply (input.voltage) 0.152979 qx_process_answer: short reply (input.voltage) 0.153082 qx_process_answer: short reply (input.voltage) 0.153758 Device not supported! 0.153846 Device not supported!

j-broo commented 2 years ago

I have a similar issue. I have two cheap UPS devices connected, it seems a lot of them use USB interfaces with no real Vendor ID, Product ID or Serial number (which is zero). Everything about them is identical aside from the port and/or device ID. These devices work with the nutdrv_qx driver. My two units below:

root@J-Pi:/etc/nut# lsusb | grep "Fry" Bus 001 Device 017: ID 0001:0000 Fry's Electronics Bus 001 Device 016: ID 0001:0000 Fry's Electronics

Sadly, NUT only detects one unit and shows the same data for both devices. There are separate entries in ups.conf. I have been looking for a way to get NUT to tell them apart, and I found this info here: Github nutdrv_qx man page

Specifically:

device = 'regex':: Select a UPS on a specific USB device or group of devices. The argument is a regular expression that must match the device name where the UPS is connected (e.g. +device="001"+, +device="00[1-2]"+). Note that device numbers are not guaranteed by the OS to be stable across re-boots or device re-plugging.

When I add the 'device' filter, the driver does not start. The 'bus' filter appears to work. I'm using NUT 2.7.4. Example:

[linkqnet] driver = nutdrv_qx port = auto bus = "001" device = "016"

It this perhaps something that only works on a newer (unreleased) version? The "device" parameter is not listed here: 2.7.4 nutdrv_qx man page

Are there any suggestions on how I can get NUT to tell these devices apart? I cannot see a way to get the driver to look at a specific port (the only option being 'auto').

arisjr commented 2 years ago

Friday I just tried the device attribute, but it only works with the git master version. The 2.7.4 version, that is the version of most packages out there, don’t have it. You have git clone and compile it from source.

The device attribute worked for me. I leaved it testing this weekend and will grab the measurement results this week.

Best regards, Aristeu

j-broo commented 2 years ago

Thanks for the confirmation. Do you perhaps have the master branch compiled for a Raspberry Pi (armhf) that you could send to me? I'm not too clued up on compiling from source.

@jimklimov does the port parameter accept anything other than 'auto'? For example, if I use udev rules to create symlinks for each UPS based on the port, would I be able to use something like /dev/ups1 as a port value to talk to the unit?

arisjr commented 2 years ago

What I did was the steps below:

$ apt-get update && apt-get install -y build-essential autoconf gettext libusb-dev git

$ git clone https://github.com/networkupstools/nut

$ cd nut

$ ./autogen.sh 

(Add the nut user and nut group before next step)

$ ./configure --prefix=/usr --with-user=nut --with-group=nut --sysconfdir=/etc/nut

$ make

$ sudo make install

...and, if I haven't forgotten some step, you'll have nut master builded on you system. 😃

arisjr commented 2 years ago

@jimklimov I have tested my new configuration and now I can confirm: The "device" attribute is working for individualizing ups devices and things are working fine. Of course, one cannot remove and reinsert the usb cable, neither restart the UPS, because the device number will change. Reinsertion of cables or restart of ups will have to be followed by a reboot of RPi to make the device numbers equal to configuration on ups.conf again. BUT, even this way, this temporarily solves my issue.

I would like one of the two following solutions, or maybe both, to be implemented:

Best regards

j-broo commented 2 years ago

@arisjr Please post an example of your config for a UPS using device parameter, from ups.conf. I'm struggling to get this working.

arisjr commented 2 years ago

@j-broo I have four usb ports on the RPi3, and I use all of them with UPS devices. If you're using another USB device plugged, you should do a "lsusb" after the rpi boot to check the UPS's usb device numbers.

/etc/nut/ups.conf

[ups-port01] driver = nutdrv_qx port = auto desc = "Voltronic Power PORT01" device = 004

[ups-port02] driver = nutdrv_qx port = auto desc = "Voltronic Power PORT02" device = 005

[ups-port03] driver = nutdrv_qx port = auto desc = "Voltronic Power PORT03" device = 006

[ups-port04] driver = nutdrv_qx port = auto desc = "Voltronic Power PORT04" device = 007

j-broo commented 2 years ago

Sadly this still does not work for me. As soon as the 'device' parameter is added, the driver service will not start. Am I running the git master build?

Nov 16 23:41:33 J-Pi upsdrvctl[2494]: Fatal error: 'device' is not a valid variable name for this driver. Nov 16 23:41:33 J-Pi upsdrvctl[2494]: Look in the man page or call this driver with -h for a list of Nov 16 23:41:33 J-Pi upsdrvctl[2494]: valid variable names and flags. Nov 16 23:41:33 J-Pi upsdrvctl[2494]: Network UPS Tools - Generic Q* USB/Serial driver 0.28 (2.7.4) Nov 16 23:41:33 J-Pi upsdrvctl[2494]: USB communication driver 0.33

EDIT: I guess not because I see this in the nutdrv_qx.c on github:

define DRIVER_VERSION "0.30"

My config:

[axil] driver = nutdrv_qx port = auto device = 006 desc = "Axil M1000K"

@arisjr I followed your procedure twice (and did an 'apt purge' of the original 2.7.4 NUT install). Sorry for being such a noob, but what did I miss?

arisjr commented 2 years ago

@j-broo You still are with the 2.7.4 version indeed.

With git version you get something like this: Network UPS Tools - UPS driver controller 2.7.4-3239-g1bd078fe Network UPS Tools - Generic Q* USB/Serial driver 0.30 (2.7.4-3239-g1bd078fe)

Sorry I can't help you further, you have to correctly remove the 2.7.4 version. And here is not the right place for this questions I guess.

jimklimov commented 2 years ago

Thanks for the report and confirmation!

Regarding new features, I must start with "PRs welcome!" in particular due to needs of a testbed setup with many USB UPSes ("identical" at that).

As for re-plug, another thread recently reminded of udev integration. To quote their example,

/etc/udev/rules.d/ 90-nut-ups.rules

ECUS UPS

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0001", ATTR{idProduct}=="0000", MODE="0664", GROUP="nut", RUN+="/usr/bin/systemctl restart nut-server.service"

On Tue, Nov 16, 2021, 12:48 arisjr @.***> wrote:

@jimklimov https://github.com/jimklimov I have tested my new configuration and now I can confirm: The "device" attribute is working for individualizing ups devices and things are working fine. Of course, one cannot remove and reinsert the usb cable, neither restart the UPS, because the device number will change. Reinsertion of cables or restart of ups will have to be followed by a reboot of RPi to make the device numbers equal to configuration on ups.conf again. BUT, even this way, this temporarily solves my issue.

I would like two of one of the following solutions, or maybe both, be implemented:

  • the nut driver to have the ability to work in port=auto without being individualized, just checking if it already is using the current tested USB device, if it's using, go to next.
  • to have the ability to individualize ports on UPS that acts as hid usb device. I have tried this individualization, as mentioned earlier in this issue, but the driver do not accept.

Best regards

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/networkupstools/nut/issues/1174#issuecomment-970193374, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAMPTFEPMCYNVHPSNPQH2D3UMJAHNANCNFSM5HYFPIBQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.