Erster Stand der Hintergrundprozesse, die auf der Synology unter /volume1/homes/wagner/SolarManager laufen: der Manager selbst, die Sammler je Geraet, die MQTT-Bruecke, der Wecker und - neu hinzugezogen - der AutoAction-Runner, der als Hintergrundprozess hierher gehoert und nicht ins Web-Verzeichnis. Zugangsdaten stehen nicht mehr im Quelltext, sondern in config.ini, die nicht mit eingecheckt wird. Vorlage ist config.ini.example, gelesen wird sie von konfig.py. Betroffen waren solarManager.py (Datenbank und Wattpilot), zeit.py, gatherWaterData.py, wecker.py und skoda_testdaten.py, das sich das Passwort bisher aus dem Quelltext eines anderen Moduls herausgesucht hat. Die Kia-Anbindung ist mit dem Fahrzeug entfallen: kiaTest.py, gatherCarData.py und hyundai_kia_connect_api sind nicht mehr dabei, ebenso gatherInverterData.py, auf das nur noch eine auskommentierte Zeile zeigte. Die mitgelieferten Bibliotheken bleiben im Repository - die NAS hat kein pip, sie muessen neben den Skripten liegen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
122 lines
3.6 KiB
Python
122 lines
3.6 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# This is a helper module for the various platform dependent list_port
|
|
# implementations.
|
|
#
|
|
# This file is part of pySerial. https://github.com/pyserial/pyserial
|
|
# (C) 2015 Chris Liechti <cliechti@gmx.net>
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import re
|
|
import glob
|
|
import os
|
|
import os.path
|
|
|
|
|
|
def numsplit(text):
|
|
"""\
|
|
Convert string into a list of texts and numbers in order to support a
|
|
natural sorting.
|
|
"""
|
|
result = []
|
|
for group in re.split(r'(\d+)', text):
|
|
if group:
|
|
try:
|
|
group = int(group)
|
|
except ValueError:
|
|
pass
|
|
result.append(group)
|
|
return result
|
|
|
|
|
|
class ListPortInfo(object):
|
|
"""Info collection base class for serial ports"""
|
|
|
|
def __init__(self, device, skip_link_detection=False):
|
|
self.device = device
|
|
self.name = os.path.basename(device)
|
|
self.description = 'n/a'
|
|
self.hwid = 'n/a'
|
|
# USB specific data
|
|
self.vid = None
|
|
self.pid = None
|
|
self.serial_number = None
|
|
self.location = None
|
|
self.manufacturer = None
|
|
self.product = None
|
|
self.interface = None
|
|
# special handling for links
|
|
if not skip_link_detection and device is not None and os.path.islink(device):
|
|
self.hwid = 'LINK={}'.format(os.path.realpath(device))
|
|
|
|
def usb_description(self):
|
|
"""return a short string to name the port based on USB info"""
|
|
if self.interface is not None:
|
|
return '{} - {}'.format(self.product, self.interface)
|
|
elif self.product is not None:
|
|
return self.product
|
|
else:
|
|
return self.name
|
|
|
|
def usb_info(self):
|
|
"""return a string with USB related information about device"""
|
|
return 'USB VID:PID={:04X}:{:04X}{}{}'.format(
|
|
self.vid or 0,
|
|
self.pid or 0,
|
|
' SER={}'.format(self.serial_number) if self.serial_number is not None else '',
|
|
' LOCATION={}'.format(self.location) if self.location is not None else '')
|
|
|
|
def apply_usb_info(self):
|
|
"""update description and hwid from USB data"""
|
|
self.description = self.usb_description()
|
|
self.hwid = self.usb_info()
|
|
|
|
def __eq__(self, other):
|
|
return isinstance(other, ListPortInfo) and self.device == other.device
|
|
|
|
def __hash__(self):
|
|
return hash(self.device)
|
|
|
|
def __lt__(self, other):
|
|
if not isinstance(other, ListPortInfo):
|
|
raise TypeError('unorderable types: {}() and {}()'.format(
|
|
type(self).__name__,
|
|
type(other).__name__))
|
|
return numsplit(self.device) < numsplit(other.device)
|
|
|
|
def __str__(self):
|
|
return '{} - {}'.format(self.device, self.description)
|
|
|
|
def __getitem__(self, index):
|
|
"""Item access: backwards compatible -> (port, desc, hwid)"""
|
|
if index == 0:
|
|
return self.device
|
|
elif index == 1:
|
|
return self.description
|
|
elif index == 2:
|
|
return self.hwid
|
|
else:
|
|
raise IndexError('{} > 2'.format(index))
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
def list_links(devices):
|
|
"""\
|
|
search all /dev devices and look for symlinks to known ports already
|
|
listed in devices.
|
|
"""
|
|
links = []
|
|
for device in glob.glob('/dev/*'):
|
|
if os.path.islink(device) and os.path.realpath(device) in devices:
|
|
links.append(device)
|
|
return links
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
# test
|
|
if __name__ == '__main__':
|
|
print(ListPortInfo('dummy'))
|