SolarManager unter Versionsverwaltung

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>
This commit is contained in:
2026-09-02 20:46:59 +02:00
co-authored by Claude Opus 5
commit 79843aa2ae
968 changed files with 261182 additions and 0 deletions
View File
+100
View File
@@ -0,0 +1,100 @@
import json
import uuid
import sunspec2.mdef as mdef
import sunspec2.device as device
import sunspec2.mb as mb
class FileClientError(Exception):
pass
class FileClientPoint(device.Point):
def read(self):
pass
def write(self):
pass
class FileClientGroup(device.Group):
def read(self):
pass
def write(self):
pass
class FileClientModel(FileClientGroup):
def __init__(self, model_id=None, model_addr=0, model_len=0, model_def=None, data=None,
group_class=FileClientGroup, point_class=FileClientPoint):
self.model_id = model_id
self.model_addr = model_addr
if model_len is None:
self.model_len = 0
else:
self.model_len = model_len
self.model_def = model_def
self.error_info = ''
self.mid = None
self.device = None
self.model = self
gdef = None
try:
if self.model_def is None and model_id is not None:
self.model_def = device.get_model_def(model_id)
if self.model_def is not None:
gdef = self.model_def.get(mdef.GROUP)
except Exception as e:
self.add_error(str(e))
FileClientGroup.__init__(self, gdef=gdef, model=self, model_offset=0, group_len=self.model_len, data=data,
data_offset=0, group_class=group_class, point_class=point_class)
def add_error(self, error_info):
self.error_info = '%s%s\n' % (self.error_info, error_info)
class FileClientDevice(device.Device):
def __init__(self, filename=None, addr=40002, model_class=FileClientModel):
device.Device.__init__(self, model_class=model_class)
self.did = str(uuid.uuid4())
self.filename = filename
self.addr = addr
def scan(self, data=None):
try:
if self.filename:
f = open(self.filename)
data = json.load(f)
mid = 0
addr = self.addr
for m in data.get('models'):
model_id = m.get('ID')
model_len = m.get('L')
if model_id != mb.SUNS_END_MODEL_ID:
model = self.model_class(model_id=model_id, model_addr=addr, model_len=model_len,
model_def=None, data=m)
model.mid = '%s_%s' % (self.did, mid)
mid += 1
self.add_model(model)
addr += model.len
except Exception as e:
raise FileClientError(str(e))
def read(self):
return ''
def write(self):
return
def close(self):
return
class FileClient(FileClientDevice):
pass