solaredge
solaredge copied to clipboard
semonitor won't open serial port if symlink
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
+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, @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 ...
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 ;-)
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).