solaredge icon indicating copy to clipboard operation
solaredge copied to clipboard

semonitor won't open serial port if symlink

Open Millox opened this issue 4 years ago • 1 comments

Hi.

I changed my udev setup today to accommodate for the multiple rs485 to usb-dongles that I use on my raspberry pi. Unfortunately semonitor does not allow the use of symlinked devices as argument -a.

Jul 24 14:10:41 saldaea semonitor[16408]: /dev/solaredge0 is not a valid serial device
Jul 24 14:10:41 saldaea semonitor[16408]: Input device types 2 and 4 are only valid for a serial device

It works if using /dev/ttyUSB1 instead. Links point to the respective character device correctly

lrwxrwxrwx  1 root root           7 Jul 24 01:53 solaredge0 -> ttyUSB0
lrwxrwxrwx  1 root root           7 Jul 24 01:53 solaredge1 -> ttyUSB1

Millox avatar Jul 24 '20 13:07 Millox

+1 for this feature request.

I call semonitor that way: ./semonitor.py -d stdout -m -s $SN -t 4 -vvvv $(readlink -f /dev/solaredge0) instead of ./semonitor.py -d stdout -m -s $SN -t 4 -vvvv /dev/solaredge0

tobylorenz avatar Apr 08 '21 10:04 tobylorenz

@tobylorenz, @Millox I tried to resolve this, but it's not so trivial. PySerial doesn't like symlinks.

I tried this patch, which didn't do what I would have expected:

Author: Olliver Schinagl <[email protected]>
Date:   Tue Jun 20 13:08:20 2023 +0200

    resolve symlinks for serial ports
    
    It is not uncommon to setup smart symlinks for hotpluggable/USB
    adapters, so they always have a known name. PySerial however seems to
    refuse to follow symlinks
    
    Signed-off-by: Olliver Schinagl <[email protected]>

diff --git a/se/env.py b/se/env.py
index bd00a3e..4319e06 100644
--- a/se/env.py
+++ b/se/env.py
@@ -117,7 +117,7 @@ def getArgs():
     elif args.datasource != "stdin":
         # figure out the list of valid serial ports on this server
         # this is either a list of tuples or ListPortInfo objects
-        serial_ports = serial.tools.list_ports.comports()
+        serial_ports = serial.tools.list_ports.comports(include_links=True)
         serial_port_names = map(lambda p: p.device if isinstance(p,
                                 serial.tools.list_ports_common.ListPortInfo) else p[0], serial_ports)
         serialDevice = args.datasource in serial_port_names
diff --git a/se/files.py b/se/files.py
index f41e6ee..18d7288 100644
--- a/se/files.py
+++ b/se/files.py
@@ -7,6 +7,8 @@ import select
 import logging
 import se.logutils
 
+from pathlib import Path
+
 logger = logging.getLogger(__name__)
 socketTimeout = 120.0
 
@@ -52,7 +54,7 @@ def openDataSocket(ports):
 
 # open serial device
 def openSerial(inFileName, baudRate):
-    return serial.Serial(inFileName, baudrate=baudRate)
+    return serial.Serial(Path(inFileName).resolve(), baudrate=baudRate)
 
 def openInFile(inFileName):
     if inFileName == "stdin":

So instead, use my dockerize feature #180 and map the serial port within docker (--device /dev/solaredge0:/dev/ttyUSB0).

@jbuehl @ericbuehl I think we can best close this issue, as this is not the fault of semonitor ...

oliv3r avatar Jul 07 '23 09:07 oliv3r

The solution with ./semonitor.py -d stdout -m -s $SN -t 4 -vvvv $(readlink -f /dev/solaredge0) works well for me.

So I don't insist on having a fix in semonitor.py to bypass a problem in Python Serial ;-)

tobylorenz avatar Jul 07 '23 13:07 tobylorenz

The solution with ./semonitor.py -d stdout -m -s $SN -t 4 -vvvv $(readlink -f /dev/solaredge0) works well for me.

So I don't insist on having a fix in semonitor.py to bypass a problem in Python Serial ;-)

Ah, yes, you are resolving the symlink before offering it :) This will work, until the symlink changes, which requires a restart of semonitor. Being able to use an actual symlink, means that if the symlink changes (via udev) there is some chance it could fix itself. But these are all very edgy edge-cases!

I couldn't use this solution myself, because I'd have to put this in my docker compose file, which can't be done, because compose won't execute the subshell. But remapping it in docker works good enough (tm) (still suffering from the same issues as I mentioned above of course).

oliv3r avatar Jul 07 '23 13:07 oliv3r