print("hi Hagen das Skript machen wir mal gemeinsam wenn Du Lust und Zeit dafür hast.") class binaryReader: def __init__(self): self.data = [] def __call__(self,s): self.data.append(str(s)) from ftplib import FTP ftp = FTP('blmgeotest.de') # connect to host, default port ftp.login("entwickler","Entwickler#1") ftp.cwd('Projekte/01logger') # change into "/pages/wiki/data/pages" directory ftp.retrlines('LIST') # optional Verzeichnisliste direkte Ausgabe auf den Bildschirm r = binaryReader() # globale Variable mit Inhalt aus Metadaten als Array ftp.retrlines('RETR MesstellenMetaDaten.txt', r) ftp.quit() # zuvor FTP gelesene configdaten als dictonary in cfgs parsen import re import pprint Standortnamen=[] # optional globale Liste mit GWM-Namen cfgs=[] # Globale Variable zum Sammeln der Metadaten for i in (3,28,53,78,103): matchObj = re.match( r'(.*):(.*?)#(.*)', r.data[i], re.M|re.I) if matchObj: #print( matchObj.group(1), matchObj.group(2), matchObj.group(3) ) sn=matchObj.group(2).strip() d = {matchObj.group(1).strip():sn} Standortnamen.append(sn) cfgs.append(d) if "Standortname" not in d.keys(): print("Fehler in der Metadatendatei Zeile:",i,"Text: 'Standortname:' erwartet") break else: print("Fehler in der Metadatendatei Zeile:",i) print(Standortnamen,len(Standortnamen)) if len(Standortnamen)!=5: print("Skript stopt. Bitte Zeilennummern der Standortnamen überprüfen! jede Messtelle hat genau 25 Zeilen!") else: offset = 0 for gwmc in cfgs: for zeile in (1,2,4,6,7,8,9,10,16,21): #print(zeile+offset,gwmc["Standortname"],r.data[zeile+offset]) matchObj = re.match( r'(.*):\s(.[^#]*\s?)\s*#?(.*)', r.data[zeile+offset], re.M|re.I) if matchObj: #print(zeile+offset, matchObj.group(1),'|', matchObj.group(2),'|' ,matchObj.group(3),'|' ) gwmc.update( {matchObj.group(1).strip():matchObj.group(2).strip()} ) else: print("Kein Match in Metadaten Zeile:",zeile+offset, r.data[zeile+offset]) break offset +=25 print("°º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸,ø¤°º¤ø,¸¸,ø¤º°`°º¤ø,¸") # Dateiliste pro Messstelle per FTP abrufen und in cfgs speichern class dirReader: def __init__(self): self.data = [] def __call__(self,s): a = s.split(" ") # von FTP-Dateiliste letzte Zeichenkette ohne , ' Zeichen als array speichern s= a[len(a)-1] self.data.append(s.strip("',")) from ftplib import FTP ftp = FTP('blmgeotest.de') # connect to host, default port ftp.login("entwickler","Entwickler#1") ftp.cwd('Projekte/01logger') # change into "/pages/wiki/data/pages" directory ftp.retrlines('LIST') # optional Verzeichnisliste direkte Ausgabe auf den Bildschirm for gwm in cfgs: logDateien = () dir = dirReader() print("######## ",gwm['Messtellennummer']," ###############",gwm['FTP-Pfad'],gwm['Standortname']) ftp.cwd(gwm['Messtellennummer']) # change into "/pages/wiki/data/pages/#" directory #ftp.retrlines('LIST') # optional Verzeichnisliste direkte Ausgabe auf den Bildschirm ftp.retrlines('LIST',dir) # abspeichern Asyncron in Variable gwm['logDateien'] = dir.data # Array in cfgs speichern ( vielleicht noch wait einbauen ) ftp.cwd('..') print("Dateien:",len(gwm['logDateien']),gwm['Standortname']) ftp.quit() ## nur die Klassendefiniton mftpReader from datetime import datetime from ftplib import FTP import re class mftpReader: def __init__(self,gwm): self.gwm = gwm self.now = datetime.now().strftime("%Y-%m-%d-%H-%M") # current date and time at start reading self.dateinummer=0 # zählt mit wieviel Kopfzeile (1.Zeile) übertragen wurden self.inputfile = "Funktion setlogInput(Dateiname) nicht aufgerufen)" self.lnum = 0 self.data = {} def getlogPegelName(self): name = str(self.gwm["Messtellennummer"])+ "_" + str(self.now)+ "_" + self.gwm["Standortname"] +"-Tage" + str(self.dateinummer) + ".pegel" return name def setlogInput(self,inputfile): self.inputfile = inputfile self.lnum = 0 #print("-- Out/In:",self.getlogPegelName()+"+1",self.inputfile) # Ausgabedateiname (2021-06-06-02-02_GWM15_17_op_101.pegel) return def getDateinummer(self): return self.dateinummer def getMetaData(self): return self.gwm def getData(self): return self.data def __call__(self,line): self.lnum += 1 #print(self.lnum,line) # Rohdaten Info if self.lnum == 1: # Kopfzeile überspringen und Dateizähler self.dateinummer +=1 if self.lnum>1: # Datenzeilen lesen und Ausgabestruktur festlegen # todo mit try um unerwartete Daten abzufangen TODO Medungsmöglichkeit bei Fehlern lelem = line.split(',') if isinstance(lelem, list) and len(lelem)==16: # es gibt 16 Spalten #print("Zeile:",lnum,len(lelem),lelem) # bei Fehlerhaften Ablauf nachfolgend die Koppfzeile in Zeile 6 #17 ['## Format=5: Datum', 'Zeit', '', '', '', '"Vbatt(V)"', '"Tintern(degC)"', '"Ueberwachungswert: Null"', 'Alarmstufe', 'GSM-Feldstaerke', '"Anzahl der externen Logger zum Senden"', 'Typ[1]', '"Wasserstand(mWS)"', 'Typ[2]', '"Temperatur(degC)"', 'Pruefsumme', '"BLM Geotest GmbH"'] outline = lelem[0]+' '+lelem[1]+'\t;'+lelem[12]+'\t;'+ "%.3f"% ( (float(self.gwm["Messpunkthöhe"].replace(",",".").replace("m",""))-float(self.gwm["Einhängetiefe"].replace(",",".").replace("m",""))+float(lelem[12])))+'\t;'+lelem[14]+'\t;'+ self.inputfile+'\t;'+ "%.3f"%( float(self.gwm["Einhängetiefe"].replace(",",".").replace("m",""))-float(lelem[12])) # # alternativ CODE 11.05.2021,00:00:00,,,,5.83,17.70,0,0,24,2,1,1.059,2,10.27,29 #matchObj = re.match( r'(.*),(.*),:\s(.[^#]*\s?)\s*#?(.*)', line, re.M|re.I) #if matchObj: # #print(zeile+offset, matchObj.group(1),'|', matchObj.group(2),'|' ,matchObj.group(3),'|' ) # gwmc.update( {matchObj.group(1).strip():matchObj.group(2).strip()} ) #else: # print("Kein Match in Metadaten Zeile:",self.lnum, self.dateiname) # Datenzeilen mit Zeitstempel zum späteren sortieren anhängen self.data.update( {self.toUnixtime(lelem[0],lelem[1]):outline} ) else: # nicht Inportierte Zeilen auf den Bildschirm mit vorrangestelter Zeilennummer ausgeben print("Zeile:",self.lnum,line) print("-- Unerwartete Rohdaten Bitte überprüfen und Skript anpassen! \n-- Dieses sollte nicht Ignoriert werden. Information nicht in Ausgabe enthalten." ) def toUnixtime(self,dateString,timeString): ''' Zeitstempel aus Datum und Zeit Zeichenkette umwandeln ''' #print('--',dateString,timeString) dateSplit = dateString.split('.') timeSplit = timeString.split(':') #datetime.datetime( year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) #print('--',int(dateSplit[2]),int(dateSplit[1]),int(dateSplit[0]) ,int(timeSplit[0]),int(timeSplit[1]),int(timeSplit[2]) ) dateObjekt = datetime(int(dateSplit[2]),int(dateSplit[1]),int(dateSplit[0]) ,int(timeSplit[0]),int(timeSplit[1]),int(timeSplit[2]) ) return dateObjekt.timestamp() def dictToPegelFile(self): n = self.getlogPegelName() dh = open(n,"w") print("-- Es wurde eine locale Datei angelegt",n) #1.Kopfzeile #self.snow: 'Datenzähler auf': '393', 'Einhängetiefe': '10,00m', 'Hochwert': '449849,068', 'Messpunkthöhe': '52,470', 'Rechtswert': '5766118,96', dh.write("# " + self.now + " Standortname:" + self.gwm['Standortname'] + " SERIALNR:" + self.gwm['SERIALNR'] + " Messtellennummer:" + self.gwm['Messtellennummer'] + " Gerätenummer:" + self.gwm['Gerätenummer'] + " DatumEinbau:" + self.gwm['DatumEinbau'] + " FTP-Pfad:" + self.gwm['FTP-Pfad']+ " Messpunkthöhe:" + self.gwm["Messpunkthöhe"] + " Einhängetiefe:" + self.gwm["Einhängetiefe"]+"\n" ) #2.Kopfzeile ("# Datum Zeit;Vbatt(V);Tintern(degC);Ueberwachungswert;Alarmstufe;GSM-Feldstaerke;Anzahl der externen Logger zum Senden;Wasserstand(mWS);Temperatur(degC);Quelldatei\n") dh.write("# Datum Zeit\t;Wasserstand(mWS)\t;WS_überNN[m];Temperatur(degC)\t;Quelldatei;Abstich[m]\n") # Todo TypeError: '<' not supported between instances of 'dict' and 'dict' # ---> 32 for k in sorted(self.data): for v in sorted(self.data): #print('--',v) # Ausgabedaten Info dh.write(self.data[v]+"\n") dh.close() # Achtung vollständiger Abruf von Rohdaten aller Messtellen !!!! Kann etwas dauern #pprint.pprint(cfgs[0].keys()) ftp = FTP('blmgeotest.de') # connect to host, default port ftp.login("entwickler","Entwickler#1") ftp.cwd('Projekte/01logger') # change into "/pages/wiki/data/pages" directory ftp.retrlines('LIST') # optional Ausgabe direkt auf dem Bildschirm outgwm={} # Globale Variable zum Sammeln der Rohdaten #for gwm in cfg: # für nur eine Messtelle zum Test for gwm in cfgs: # für alle Mestellen ftp.cwd(gwm["Messtellennummer"]) # in MesstellennummerOrdner 101 102 135 136 137 wechseln #Zeilennummer ----------------------------------------- gelesene Rohdaten #1 ## Format=5: Datum,Zeit,,,,"Vbatt(V)","Tintern(degC)","Ueberwachungswert: Null",Alarmstufe,GSM-Feldstaerke,"Anzahl der externen Logger zum Senden",Typ[1],"Wasserstand(mWS)",Typ[2],"Temperatur(degC)",Pruefsumme,"BLM Geotest GmbH" #2 20.11.2020,12:17:00,,,,6.18,17.22,0,0,11,2,1,-0.002,2,19.03,07 #3 20.11.2020,13:17:00,,,,6.18,17.22,0,0,11,2,1,-0.002,2,19.03,06 #4 20.11.2020,14:17:00,,,,6.18,16.90,0,0,11,2,1,-0.002,2,19.04,0E ## .... #25 21.11.2020,10:34:56,,,,6.15,18.02,0,0,11,2,1,0.000,2,17.60,22 #26 21.11.2020,10:43:16,,,,6.16,17.86,0,0,11,2,1,0.000,2,17.47,23 # BLM-Geotest-GmbH_A32579_659272641.txt 1 von 196 log-Dateiname bis # #24 05.06.2021,10:00:00,,,,5.82,22.14,0,0,24,2,1,1.054,2,10.35,25 #25 05.06.2021,11:00:00,,,,5.83,23.25,0,0,24,2,1,1.054,2,10.37,24 #BLM-Geotest-GmbH_A32579_676207040.txt 196 von 196 letzte logdatei im 101-Ordner # ----------------------- txth = mftpReader(gwm) for txt in gwm["logDateien"]: txth.setlogInput(txt) ftp.retrlines("RETR " + txt, txth) print(txt ,txth.getDateinummer(),"von",len(gwm["logDateien"]) ) ftp.cwd("..") #txth.dictToPegelFile(outfileString) # Versuch gleich zu speichern outgwm[txth.getlogPegelName()] = txth # übergabe zum nächsten Schritt Achtung Sync (abwarten bi fertig) #print(txth.data) ftp.quit() print(outgwm.keys()) #schluessel = '2021-06-09-13-27_GWM11_1_07-137-Tage206.pegel #pprint.pprint(outgwm[schluessel]) #gwm1=outgwm[schluessel].getMetaData() #print(gwm1) print("========================================================================") #gwm1d = outgwm[schluessel].getData() #print(gwm1d) #for k,v in outgwm['2021-06-06-14-56_GWM3_3_02_135.pegel']: # print(k," <:> ",v) # ein Versuch zu speichern nachdem alles eingelesen war. for outfile, v in outgwm.items(): #print("speichere",outfile) v.dictToPegelFile()