Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Smart automation for correct port detection #287

Closed
Saentist opened this issue Dec 23, 2022 · 13 comments
Closed

[FR] Smart automation for correct port detection #287

Saentist opened this issue Dec 23, 2022 · 13 comments
Milestone

Comments

@Saentist
Copy link
Contributor

On my PC there is a few USB devices which are HIDRAW(0-5)
but after restart they changed ordering.
If inverter was "hidraw1" next time is "hidraw5"

there is a simple bash script for detection

#!/bin/bash

FILES=/dev/hidraw*
for f in $FILES
do
  FILE=${f##*/}
  DEVICE="$(cat /sys/class/hidraw/${FILE}/device/uevent | grep HID_NAME | cut -d '=' -f2)"
  printf "%s \t %s\n" $FILE "$DEVICE"
done

In my case result is:

hidraw0          American Power Conversion  Smart-UPS C 1500 FW:UPS 10.0 / ID
hidraw1          STMicroelectronics HID in FS Mode   <<< Inverter 0665:5161 Cypress Semiconductor USB to Serial
hidraw2          HID TOUCH HID Touch Panel
hidraw3          SIGMACHIP USB Keyboard
hidraw4          SIGMACHIP USB Keyboard

How can make automatic hidraw detection and selection,
without hard selecting and avoid after restart non working results?

@jblance
Copy link
Owner

jblance commented Dec 23, 2022

bit out of scope of my code
the way to do it is with udev rules - once done correctly they will allow permanent names for the devices even with reboots
eg https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name

@Saentist
Copy link
Contributor Author

Sorry maybe stupid question but:
This will not work or even will destroy communication,
if there is more then one inverter connected to PC.
Just because inverters use same communication chip aka VID:PID.

Isn't more logical to have some "in start" code,
with to check all hidrawX/ttyUSBx with QID#QPI#QMN#QVFW#QVFW2#QVFW3 command

mpp-solar -p /dev/hidraw1 -o raw -c QID#QPI#QMN#QVFW#QVFW2#QVFW3
Processing DEFAULT type responses
Command: QID - Device Serial Number inquiry
------------------------------------------------------------
raw_response                    '(553555355535552\xfd\r'
Processing DEFAULT type responses
Command: QPI - Protocol ID inquiry
------------------------------------------------------------
raw_response                    '(PI30\x9a\x0b\r'
Command: QMN - No description found     <<<< Inverter Model
------------------------------------------------------------
raw_response                    "(VMIII-5000\xa8'\r"
Processing DEFAULT type responses
Command: QVFW - Main CPU firmware version inquiry
------------------------------------------------------------
raw_response                    '(VERFW:00091.20\xf8&\r'
Command: QVFW3 - No description found     <<<< Bluetooth Firmware
------------------------------------------------------------
raw_response                    '(VERFW:00002.61\x17c\r'

And if there is no problem with "Device Serial Number" aka 55355535553555 or device cloning
this information is enough to match "path to device"


This can be new functionality

mpp-solar -detect-inverter 

with will display inverter hardware information and eventually suggest "install as service"

@jblance
Copy link
Owner

jblance commented Dec 24, 2022 via email

@Saentist
Copy link
Contributor Author

Saentist commented Jun 7, 2023

Still interested to see some automation in detection...

import glob
import os

for f in glob.glob("/dev/hidraw*"):
    with open(os.path.join("/sys/class/hidraw", os.path.basename(f), "device/uevent")) as uevent_file:
        device_name = None
        for line in uevent_file:
            if line.startswith("HID_NAME="):
                device_name = line[len("HID_NAME="):].strip()
                break
        print(f"{os.path.basename(f)}\t{device_name}")

now I have this result

hidraw2 STMicroelectronics HID in FS Mode
hidraw1 HID TOUCH HID Touch Panel
hidraw0 American Power Conversion  Smart-UPS C 1500 FW:UPS 10.0 / ID=1005

Question is how software to use automatically hidrawX STMicroelectronics HID in FS Mode (0665:5161 Cypress Semiconductor USB to Serial),
when usb cable used?

@jblance
Copy link
Owner

jblance commented Jun 7, 2023

I still think this is the wrong approach - you are better to use udev rules (and base it off physical path if you have multiple)
If you are worried about multiple inverters causing issues with udev, you will have the same problem with the above giving duplicate results

@Saentist
Copy link
Contributor Author

Saentist commented Jun 7, 2023

Problem i see is that hidraw arrange is different after any restart
Some how APC is always hidraw0 but after is random if keyboard mouse attached bigger mess

USB port have unique address in system, and can see what is attached there.
if VID:PID 0665:5161 is there
then compare with hidraw attached to it
get serial number of inverter
search if next
start service without manual port configuration

@jblance
Copy link
Owner

jblance commented Jun 7, 2023

but the cable is always in the same physical port, so you can use that in udev to create an unchanging symlink

@Saentist
Copy link
Contributor Author

Saentist commented Jun 8, 2023

maybe I need to make video
same usb port
simple restart
Result hidraw are rearranged but APC is always hidraw0
hidraw1 and 2 are randomly assigned to Inverter and AIO PC Touchscreen

@jblance
Copy link
Owner

jblance commented Jun 8, 2023 via email

@jblance jblance modified the milestones: 0.16 release, 0.17 release Jul 13, 2023
@michas79de
Copy link
Contributor

michas79de commented Aug 12, 2023

I also prefer udev rules instead of any automation.
Then I hope my Home Assistant can use command switches to the proper ports.

With two same cables, I get the same VID:PID combinations. But with their serial numbers I can use rules.
Now my inverter is at /dev/inverter:

$ ls -l /dev/inverter
lrwxrwxrwx 1 root root 7 12. Aug 21:48 /dev/inverter -> ttyUSB0

But it doesn't seem to work. Though it points to the correct port, mpp-solar doesn't understand it:

$ mpp-solar -p /dev/inverter -c QPI
2023-08-12 22:07:58,834:ERROR:device:run_command@56: No communications port defined - unable to run command QPI
Command: Unknown command - No description found
--------------------------------------------------------------------------------
Parameter Value                 Unit
error     No communications port defined - unable to run command QPI

But with the direct port it works:

$ mpp-solar -p /dev/ttyUSB0 -c QPI
Command: QPI - Protocol ID inquiry
--------------------------------------------------------------------------------
Parameter   Value               Unit
protocol_id PI30

So how do I have to use this?

@michas79de
Copy link
Contributor

In the meantime I flew over your code and found some kind of filter check.
After renaming to /dev/ttyusbinverter it fulfils the condition

    elif "ttyusb" in port:
        log.debug("port matches ttyusb")
        return PortType.SERIAL

and works nice now:

$ mpp-solar -p /dev/ttyusbinverter -c QPI
Command: QPI - Protocol ID inquiry
--------------------------------------------------------------------------------
Parameter   Value               Unit
protocol_id PI30

So for me it's solved. But I let it here, maybe it's helpful for others.

@jblance
Copy link
Owner

jblance commented Aug 13, 2023

alternatively you need to tell it what type of port you are using, eg
$ mpp-solar -p /dev/inverter -c QPI --porttype serial

@jblance
Copy link
Owner

jblance commented May 13, 2024

in powermon code

@jblance jblance closed this as completed May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

3 participants