# Teile einer CSV oder DB3 Datei auslesen



## mstut (26. Juni 2022)

Hallo

Ein Programm liest die Fritz Box Steckdosen aus und erstellt eine CSV und eine DB3 Datei, ein mal pro Minute.
Leider habe ich keine Ahnung wie das geht und Hoffe das jemand so nett ist mir zu helfen.

Ich möchte gerne nur von einer Steckdose die letzten x Daten, das Datum und die Uhrzeit, am besten getrent, die LeistungWatt und ZaehlerStrom.
Am besten alles Variabel. In der SCV Datei ist die Reihenfolgen irgen wie anders.

Dann möcht ich die erzeigte Datei, zb. TXT auf meine HP übertragen und anzeigen.
Den Inhalt sollte ich direkt einfügen oder mit PHP auslesen können.

mfg
Michael


----------



## Sempervivum (26. Juni 2022)

PHP unterstützt das CSV-Format:
PHP: fgetcsv - Manual
Damit kannst du die Datei in ein Array einlesen und mit den gängigen Mitteln, z. B. sortieren und als HTML ausgeben.


----------



## mstut (26. Juni 2022)

Hallo

Danke für die info.
Ja, auslesen geht ja noch aber jetzt die letzten x Zeile auslesen ist mein Problem.
Und dann, es sind seit dem 1.1.2022 1,3 Millionen Datenreihen vorhanden.
Sagen wir mal alle 10 Minuten diese große Datei ubertragen und dann mit PHP auslesen, das dauert schon etwas.
Einfacher ist es, wenn ein Script auf dem PC das übernimmt und ich nur noch die kleine Datei übertragen muss.

mfg
Michael


----------



## Sempervivum (26. Juni 2022)

Also diese Datei liegt erst Mal noch nicht auf deinem Webserver sondern auf deinem PC. Und wo liegt dann der Webserver?
Du kannst natürlich auch mit einem Skript, z. B. in Python, auf dem PC die Datei vorverarbeiten und das heraus filtern was Du brauchst. Und dann auf den Webserver übertragen. Python unterstützt natürlich auch CSV und FTP.


----------



## mstut (26. Juni 2022)

Hallo

Mit PHP kenne ich mit etwas aus aber alles andere nicht.
Deshalb habe ich ja hier um Hilfe gebeten.

mfg
Michael


----------



## Sempervivum (26. Juni 2022)

OK, aber um dir zu helfen, muss man erst Mal die Randbedingungen kennen. Trifft das denn zu was ich vermute? Die CSV-Datei wird automatisch auf deinem PC abgelegt, muss dort vorverarbeitet werden mit einem geeigneten Skript, das von deinem Betriebssystem unterstützt wird und das Ergebnis dann mit FTP auf deinen Webserver übertragen? Python ist nur eine Vorliebe von mir persönlich weil ich Batch zu kryptisch und unhandlich finde und ich mich mit Powershell nicht anfreunden konnte. Was für ein Betriebssystem läuft denn auf deinem PC?


----------



## mstut (26. Juni 2022)

Hallo

Ich betreibe eine Wetterstation mit einem 24/7 PC und Win 10.
Auf dem PC werden die Daten aus der Wetterstation ausgewertet und alle 10 Minuten auf die HP übertragen.
HP siehe unten.
Dann habe ich noch ein Balkonkraftwerk und die Software Dect!Read die die CSV Datei erzeugt.
5 Fritz Box Steckdosen und 1 Datensatz pro Minute.
Ich möchte gerne die Daten des Balkonkraftwerks aus der CSV Datei auf der HP darstellen.
Aber nur die letzten x Minuten ( Stunden ).
Was genau muss ich erst sehen wenn es Funktioniert.
Also die z.b. die Spannung oder Temperatur benötige ich nicht.

mfg
Michael


----------



## Sempervivum (26. Juni 2022)

Dann poste doch mal einige Zeilen dieser CSV-Datei in Textform, nicht als Bild, oder stelle sie irgend wo zum Herunterladen zur Verfügung.


----------



## mstut (26. Juni 2022)

Hallo

Hier eine Test Datei gelöscht

mfg
Michael


----------



## Sempervivum (26. Juni 2022)

OK, danke, ich werde da etwas mit Python zurecht machen, kann aber eine Weile dauern.


----------



## mstut (26. Juni 2022)

Ok, Danke kein Problem, hat Zeit


----------



## Sempervivum (26. Juni 2022)

Kurze Rückfrage, du schriebst "nur von einer Steckdose". Ich nehme an, die erste Spalte ist offenbar die AIN und enthält so eine Art ID, die angibt, von welcher Steckdose die Daten sind?


----------



## mstut (26. Juni 2022)

ja, so ist es
auf den ersten Bildern sieht man es


----------



## Sempervivum (26. Juni 2022)

OK, danke!


----------



## Sempervivum (26. Juni 2022)

So, ich habe eine Basisversion des Skripts fertig. Du musst dann Python auf dem PC installieren, damit es laufen kann. Zum Testen zunächst direkt starten durch Doppelklick oder Aufruf in der Eingabeaufforderung.
Das Skript benutzt FTP mit TLS und zwar musste ich auf dem FTP-Server als SSL-Modus "Explicit" einstellen.

```
import sys
import os
import time
from csv import reader
import json
from ftplib import FTP
from ftplib import FTP_TLS
import io

try:
    # Intervall in Sekunden für das Prüfen der CSV-Datei:
    intv = 10
    # Parameter in der CSV-Datei
    # Schlüssel: Frei wählbarer Name
    # Wert: Der Index in der CSV-Zeile
    confParams = {
        'AIN': 0,
        'voltage': 1,
        # bei den folgenden Parametern wusste ich die Bedeutung nicht
        # ergänze sie
        'date': 5,
        'time': 6
    }
    # AIN der Steckdose, die gelesen werden soll:
    ainToRead = '116570450402'
    # Dateiname der CSV-Datei:
    filename = 'DectRead_test.csv'
    # Dateiname unter dem die JSON-Datei
    # auf dem FTP-Server abgelegt werden soll:
    ftpFilename = 'dect-read.json'
    # FTP-Server, Name oder IP:
    ftpServer = ''
    # FTP-Port:
    ftpPort = 2221
    # Benutzername für FTP:
    ftpUser = ''
    # Passwort für FTP:
    ftpPasswd = ''
    # Verzeichnis auf dem FTP-Server:
    ftpDir = ''

    # Ab hier braucht nichts mehr geändert zu werden

    # Verzeichnis dieser Skriptdatei ermitteln:
    dir = os.path.dirname(os.path.realpath(__file__))
    # Wir gehen davon aus,
    # dass Skript und CSV-Datei im selben Verzeichnis liegen:
    path = dir + '\\' + filename
    # Merker für Zeitstempel:
    tim = 0
    # Endlosschleife:
    while True:
        # Zeit der letzten Änderung der CSV-Datei ermitteln:
        mtime = os.path.getmtime(path)
        # Hat sich die Zeit geändert?
        if(mtime > tim):
            # Neue Zeit merken:
            tim = mtime
            # CSV-Datei öffnen:
            with open(path, 'r') as read_obj:
                output = []
                # pass the file object to reader() to get the reader object
                csv_reader = reader(read_obj)
                # Iterate over each row in the csv using reader object
                for row in csv_reader:
                    # row variable is a list that represents a row in csv
                    # print(row)
                    # Gilt die Zeile für die Steckdose, die übertragen werden soll?
                    if row[confParams['AIN']] == ainToRead:
                        # Alle Parameter zum Ausgabe-Array hinzu fügen:
                        params = {}
                        for key in confParams:
                            params[key] = row[confParams[key]]
                        output.append(params)
                # Ausgabe-Array in JSON kodieren:
                outputJson = json.dumps(output)
                print(outputJson)
                # Mit FTP-Server verbinden und JSON hochladen:
                # ftp = FTP()
                ftp = FTP_TLS()
                ftp.connect(ftpServer, ftpPort)
                ftp.login(ftpUser, ftpPasswd)
                ftp.prot_p()
                ftp.cwd(ftpDir)
                bio = io.BytesIO()
                bio.write(outputJson.encode())
                bio.seek(0)  # move to beginning of file
                ftp.storbinary('STOR ' + ftpFilename, bio)
                ftp.close()
        # Konfigurierte Zeit warten:
        time.sleep(intv)
except:
    print("Error at line", sys.exc_info()[2].tb_lineno, sys.exc_info())
# Zum testen, damit wir die Fehleranzeigen zu Gesicht bekommen:
input()
```
Gefiltert wird noch nichts außer der AIN. Versuche zunächst ob es so bei dir läuft.


----------



## mstut (26. Juni 2022)

Hallo
Da sind sie wieder, meine Probleme.
Ich bekomme keine Verbindung, liegt bestimmt am SSL.
Error at line 81
Bin bei Domain Factory und habe dort nichts gefunden.
Kann man nicht einfach die Datei auf dem PC speichern?
Kann heute erst ein mal nicht weiter machen.
mfg
Michael


----------



## Sempervivum (26. Juni 2022)

> Kann man nicht einfach die Datei auf dem PC speichern?


Mit dem FTP hatte ich auch einige Probleme bis es lief. Natürlich kann man die Datei auch auf dem PC speichern aber Du willst die Daten ja auf der Website anzeigen. Ich wollte erst fragen: "Läuft dein Webserver denn auf dem selben PC?" aber da Du von Domainfactory schreibst, wird die HP offenbar dort gehostet.


----------



## mstut (26. Juni 2022)

In Post 7 hatte ich das ja geschrieben, alle 10 Min. auf die HP.
Was ist das dann für eine Datei die erzeugt wird?
Kann ich die dann in meine Seite einfügen, zb. als Tabelle oder Liste?
So jetzt muss ich aber weg.
mfg


----------



## Sempervivum (26. Juni 2022)

Das ist eine JSON-Datei, die Du problemlos in PHP einlesen kannst. Muss aber, wenn ich das richtig verstehe, automatisch erfolgen, einschl. des Hochladens auf deine HP.


----------



## Sempervivum (26. Juni 2022)

Laut Doku von Domainfactory wird SFTP unterstützt. Ich habe das Skript mal darauf angepasst:

```
import sys
import os
import time
import datetime
from csv import reader
import json
import paramiko
import io
import ftplogin

try:
    # Intervall in Sekunden für das Prüfen der CSV-Datei:
    intvPoll = 10
    # Anzahl von Datensätzen, die aus der
    # CSV-Datei übernommern werden sollen:
    nrData = 10
    # Intervall in Sekunden, in dem die CSS-Datei
    # aktualisiert wird:
    intvCsv = 600  # 10 Minuten
    # Parameter in der CSV-Datei
    # Schlüssel: Frei wählbarer Name
    # Wert: Der Index in der CSV-Zeile
    confParams = {
        'AIN': 0,
        'Spannung': 1,
        'Leistung': 2,
        'Zählerstand': 3,
        'Temperatur': 4,
        'Datum': 5,
        'Zeit': 6
    }
    # AIN der Steckdose, die gelesen werden soll:
    ainToRead = '116570450402'
    # Dateiname der CSV-Datei:
    filename = 'DectRead_test.csv'

    # Ab hier braucht nichts mehr geändert zu werden

    # Zeitraum, innerhalb dessen Daten übernommen werden sollen
    # bzw. maximales Alter der Daten:
    maxAge = nrData * intvCsv
    # Verzeichnis dieser Skriptdatei ermitteln:
    dir = os.path.dirname(os.path.realpath(__file__))
    # Wir gehen davon aus,
    # dass Skript und CSV-Datei im selben Verzeichnis liegen:
    path = dir + '\\' + filename
    # Merker für Zeitstempel:
    tim = 0
    # Endlosschleife:
    while True:
        # Zeit der letzten Änderung der CSV-Datei ermitteln:
        mtime = os.path.getmtime(path)
        # Hat sich die Zeit geändert?
        if(mtime > tim):
            # Neue Zeit merken:
            tim = mtime
            now = datetime.datetime.now()
            # CSV-Datei öffnen:
            with open(path, 'r') as read_obj:
                output = []
                # pass the file object to reader() to get the reader object
                csv_reader = reader(read_obj)
                # Iterate over each row in the csv using reader object
                for row in csv_reader:
                    # row variable is a list that represents a row in csv
                    # print(row)
                    # Zeit für die aktuelle Zeile ermitteln:
                    timeRow = datetime.datetime.strptime(
                        row[confParams['Datum']] + 'T' + row[confParams['Zeit']], "%Y-%m-%dT%H:%M:%S")
                    # Alter der Daten ermittteln durch Subtrahieren der Zeit der Zeile
                    # von der Jetzt-Zeit:
                    ageRow = (now - timeRow).total_seconds()
                    # Ist das Alter der Zeile kleiner als das konfigurierte maximale?
                    if ageRow < maxAge:
                        # Gilt die Zeile für die Steckdose, die übertragen werden soll?
                        if row[confParams['AIN']] == ainToRead:
                            # Alle Parameter zum Ausgabe-Array hinzu fügen:
                            params = {}
                            for key in confParams:
                                params[key] = row[confParams[key]]
                            output.append(params)
                # Ausgabe-Array in JSON kodieren:
                outputJson = json.dumps(output)
                bio = io.BytesIO()
                bio.write(outputJson.encode())
                bio.seek(0)  # move to beginning of file
                print(bio.getvalue())

                # Mit FTP-Server verbinden und JSON hochladen:
                # Create a Transport object
                transport = paramiko.Transport(
                    (ftplogin.ftpServer, ftplogin.ftpPort))
                # Connect to a Transport server
                transport.connect(username=ftplogin.ftpUser,
                                  password=ftplogin.ftpPasswd)
                sftp = paramiko.SFTPClient.from_transport(transport)

                # Upload file to server
                sftp.putfo(bio, ftplogin.ftpPath)
                # print(sftp.listdir('./'))

                sftp.close()
                transport.close()
        # Konfigurierte Zeit warten:
        time.sleep(intvPoll)
except:
    print("Error at line", sys.exc_info()[2].tb_lineno, sys.exc_info())
# Zum testen, damit wir die Fehleranzeigen zu Gesicht bekommen:
input()
```
Die FTP-Daten habe ich in eine Datei ftplogin.py ausgelagert:

```
# FTP-Server, Name oder IP:
ftpServer = 'server'
# FTP-Port:
ftpPort = 22
# Benutzername für SFTP:
ftpUser = 'username'
# Passwort für SFTP:
ftpPasswd = 'password'
# Pfad auf dem FTP-Server einschl. Dateiname:
ftpPath = 'path-on-server'
```
Das Skript braucht jetzt die Erweiterung paramiko. Diese musst Du installieren mit

```
pip install paramiko
```
in der Eingabeaufforderung.


----------



## Zvoni (27. Juni 2022)

Wieso so umständlich?
Wenn ich die Webseite von Dect!Read richtig lese, kann man direkt in eine SQLite oder MySQL schreiben.
Dann sind es simple SELECTs

EDIT: Würde eher zu MySQL tendieren, da (mindestens) zwei Clients auf die Datenbank zugreifen:
Dect!Read schreibend, und deine Webseite lesend
SQLite kann man zwar für concurrent access "konfigurieren", macht aber keinen Spass....


----------



## mstut (27. Juni 2022)

Hallo

Erst ein mal vielen Dank für deine Hilfe,
aber das ist nicht das was ich wollte. Ist mir viel zu kompliziert.
Ich möcht nichts Installieren oder mich Stunden lang mit FTP beschäftigen.
Kleine Änderungen sollten für mich ohne Hilfe möglich sein.
Ich habe gedacht, das es wesentlich einfacher ist das umzusetzen.

Ich habe mir aber heute noch ein mal Gedanken gemacht und in der Arbeitspause im Netz gesucht.
Ich kann die CSV Datei in Abständen von zb. 1 Tag oder 1 Woche verschieben oder umbenennen und Dect Read erzeugt automatisch eine neu CSV. Die ist dann sehr klein und zum Übertragen ok.
Und ich habe noch ein Script gefunden das so etwas macht was ich suche.
Nur es werden alle AINs und alle Daten angezeigt.
Aber ich weiß nicht, ob man das Scrips verwenden darf und es müsste dann angepasste werden.

Ich hoffe das das ok ist und ich niemanden verärgert habe.

mfg
Michael


----------



## Zvoni (27. Juni 2022)

Was soll daran kompliziert sein? Und was hat das mit FTP zu tun?
Es sei denn, diese Webseite hostest du nicht selbst, sondern bei einem externen Anbieter.
wenn du selbst hostest, ist alles im internen Netzwerk, und da ist es ziemlich einfach MySQL aufzusetzen


----------



## mstut (27. Juni 2022)

Kannst Du mir sagen wie eine Kontroll Wechsel Schaltung funktioniert?
und siehe Post 7
mfg


----------



## Sempervivum (27. Juni 2022)

> aber das ist nicht das was ich wollte. Ist mir viel zu kompliziert.
> Ich möcht nichts Installieren oder mich Stunden lang mit FTP beschäftigen.
> Kleine Änderungen sollten für mich ohne Hilfe möglich sein.
> Ich habe gedacht, das es wesentlich einfacher ist das umzusetzen.


Manchmal ist es so, dass man den Pelz des Bären nicht waschen kann ohne ihn nass zu machen.
Möglicher Weise bin ich bei meinem Skript jedoch von falschen Voraussetzungen aus gegangen: Weil Du Domainfactory ins Spiel gebracht hast, habe ich angenommen, dass deine Website dort gehostet wird während diese CSV-Datei auf deinem eigenen PC liegt. Und dann hätten wir die Dateien mit FTP dort hin übertragen müssen. Trifft das denn jetzt zu oder hast Du auf deinem eigenen PC einen Webserver laufen und hostest deine Website selber?


----------



## mstut (27. Juni 2022)

> Weil Du Domainfactory ins Spiel gebracht hast, habe ich angenommen, dass deine Website dort gehostet wird während


Ich habe keinen eigenen Webserver und die Seite ist bei DF.


> während diese CSV-Datei auf deinem eigenen PC liegt


Die CSV ist auf dem PC wo ja auch DR ist und die Datei erzeugt.


> Und dann hätten wir die Dateien mit FTP dort hin übertragen müssen


Es gibt ein Übertragungsprogramm auf dem PC das die Wetter Daten alle 10 Minuten überträgt.
Es gibt einen Ordner auf dem PC der mit dem gleichen Ordner auf DF Synchronisier wird.
Wenn die CSV in diesem Ordner liegt wird sie mit Übertragen.

mfg


----------



## Sempervivum (27. Juni 2022)

> Es gibt ein Übertragungsprogramm auf dem PC das die Wetter Daten alle 10 Minuten überträgt.
> Es gibt einen Ordner auf dem PC der mit dem gleichen Ordner auf DF Synchronisier wird.
> Wenn die CSV in diesem Ordner liegt wird sie mit Übertragung.


Das ist jetzt natürlich eine ganz wichtige Info, die bisher gefehlt hat und dann braucht es allerdings kein FTP.

BTW: Das PHP-Skript, das Du da gefunden hast, ist auch nicht nennenswert einfacher als mein Python-Skript


----------



## mstut (27. Juni 2022)

Entweder die Auswertung auf der HP mit PHP und die CSV kleiner machen und Übertragen
oder alles auf dem PC erstellen und nur das Ergebniss übertragen
mfg


----------



## mstut (27. Juni 2022)

so in etwa habe ich mir das vorgestellt, siehe Bild
mfg


----------



## Sempervivum (27. Juni 2022)

Ich habe mal das FTP aus meinem Skript heraus genommen und statt dessen die Daten in eine JSON-Datei geschrieben. Sieht dann so aus:

```
import sys
import os
import time
import datetime
from csv import reader
import json

try:
    # Intervall in Sekunden für das Prüfen der CSV-Datei:
    intvPoll = 10
    # Anzahl von Datensätzen, die aus der
    # CSV-Datei übernommern werden sollen:
    nrData = 10
    # Intervall in Sekunden, in dem die CSS-Datei
    # aktualisiert wird:
    intvCsv = 600  # 10 Minuten
    # Parameter in der CSV-Datei
    # Schlüssel: Frei wählbarer Name
    # Wert: Der Index in der CSV-Zeile
    confParams = {
        'AIN': 0,
        'Spannung': 1,
        'Leistung': 2,
        'Zaehlerstand': 3,
        'Temperatur': 4,
        'Datum': 5,
        'Zeit': 6
    }
    # AIN der Steckdose, die gelesen werden soll:
    ainToRead = '116570450402'
    # Dateiname der CSV-Datei:
    filenameInCsv = 'DectRead_test.csv'
    filenameOutJson = 'dect-read.json'

    # Ab hier braucht nichts mehr geändert zu werden

    # Zeitraum, innerhalb dessen Daten übernommen werden sollen
    # bzw. maximales Alter der Daten:
    maxAge = nrData * intvCsv
    # Verzeichnis dieser Skriptdatei ermitteln:
    dir = os.path.dirname(os.path.realpath(__file__))
    # Wir gehen davon aus,
    # dass Skript und CSV-Datei im selben Verzeichnis liegen:
    pathIn = dir + '\\' + filenameInCsv
    pathOut = dir + '\\' + filenameOutJson
    # Merker für Zeitstempel:
    tim = 0
    # Endlosschleife:
    while True:
        # Zeit der letzten Änderung der CSV-Datei ermitteln:
        mtime = os.path.getmtime(pathIn)
        # Hat sich die Zeit geändert?
        if(mtime > tim):
            # Neue Zeit merken:
            tim = mtime
            now = datetime.datetime.now()
            # CSV-Datei öffnen:
            with open(pathIn, 'r') as fileIn:
                output = []
                # pass the file object to reader() to get the reader object
                csv_reader = reader(fileIn)
                # Iterate over each row in the csv using reader object
                for row in csv_reader:
                    # row variable is a list that represents a row in csv
                    # print(row)
                    # Zeit für die aktuelle Zeile ermitteln:
                    timeRow = datetime.datetime.strptime(
                        row[confParams['Datum']] + 'T' + row[confParams['Zeit']], "%Y-%m-%dT%H:%M:%S")
                    # Alter der Daten ermittteln durch Subtrahieren der Zeit der Zeile
                    # von der Jetzt-Zeit:
                    ageRow = (now - timeRow).total_seconds()
                    # Ist das Alter der Zeile kleiner als das konfigurierte maximale?
                    if ageRow < maxAge:
                        # Gilt die Zeile für die Steckdose, die übertragen werden soll?
                        if row[confParams['AIN']] == ainToRead:
                            # Alle Parameter zum Ausgabe-Array hinzu fügen:
                            params = {}
                            for key in confParams:
                                params[key] = row[confParams[key]]
                            output.append(params)
                # Ausgabe-Array in JSON kodieren:
                with open(pathOut, 'w') as fileOut:
                    fileOut.write(json.dumps(output))
        # Konfigurierte Zeit warten:
        time.sleep(intvPoll)
except:
    print("Error at line", sys.exc_info()[2].tb_lineno, sys.exc_info())
# Zum testen, damit wir die Fehleranzeigen zu Gesicht bekommen:
input()
```
Welche Daten übernommen werden kannst Du über die Variable confParams steuern.
Ausgabe in eine Tabelle dann z. B. so:

```
<table>
        <tbody>
<?php
$data = json_decode(file_get_contents('dect-read.json'));
foreach ($data as $row) {
    echo "
            <tr>
                <td>$row->Spannung</td>
                <td>$row->Leistung</td>
                <td>$row->Zaehlerstand</td>
                <td>$row->Temperatur</td>
                <td>$row->Datum</td>
                <td>$row->Zeit</td>
            </tr>
";
}
?>
        </tbody>
    </table>
```
Kopf kannst Du selbst hinzu fügen.


----------



## mstut (27. Juni 2022)

ok, Danke
werde ich morgen mal Testen.
mfg


----------



## mstut (28. Juni 2022)

Hallo
Ich habe das jetzt mal getestet, aber es geht nicht.
mfg
Michael


----------



## ByeBye 284669 (28. Juni 2022)

mstut hat gesagt.:


> aber es geht nicht.


Sehr schöne Problembeschreibung   

Die Json-Datei ist gerade mal 2 Byte groß, da steht wohl nicht viel drin.


----------



## Sempervivum (28. Juni 2022)

So sehr schlecht sieht das gar nicht aus, Fenster schwarz ist in diesem Fall positiv zu bewerten, da keine Fehler angezeigt werden. Auch dass das JSON angelegt wurde ist positiv. Das einzige Problem besteht darin, dass das Array in dem JSON leer ist, denn die Dateigröße beträgt 2.
Das hatte ich beim Testen auch und es liegt daran, dass die Daten in der CSV-Datei zu alt sind. Es werden 10 Datensätze in der Vergangenheit übernommen, bei einer Aktualisierung alle 10 Minuten ergibt sich ein Zeitraum von 100 Minuten in die Vergangenheit.
Versuche, eine aktuelle Datei zu verwenden oder in der vorhandenen das Datum oder die Zeit entspr. zu ändern. Wenn es dann immer noch nicht funktioniert sehen wir weiter.


----------



## mstut (28. Juni 2022)

Ich habe mal die Aktuelle Datei vom Wetter PC genommen
jetzt gibt es eine Fehlermeldung
mfg


----------



## mstut (28. Juni 2022)

m.scatello hat gesagt.:


> Sehr schöne Problembeschreibung


Dafür gibt es ja ein Bild und das sagt meh als viele Worte.
mfg


----------



## Sempervivum (28. Juni 2022)

Hast Du evtl. die confParam angepasst? AIN sowie Datum und Zeit müssen immer drin sein, auch wenn Du etwas davon nicht anzeigen willst.


----------



## ByeBye 284669 (28. Juni 2022)

mstut hat gesagt.:


> Dafür gibt es ja ein Bild und das sagt meh als viele Worte.


Wie wäre es denn mal mit Fehler selber suchen? Aber Sempervivum kann es ja nicht lassen und schreibt fertige Scripte


----------



## Sempervivum (28. Juni 2022)

PS: Bei meinen Tests bin ich von dem Stand in der Testdatei von Posting #5 ausgegangen. Dort sind Datum und Uhrzeit durch Komma getrennt, d. h. verschiedene Felder.
In dem Bild in #1 sind beide jedoch durch Leerzeichen getrennt in einem Feld. Was ist jetzt richtig?


----------



## mstut (28. Juni 2022)

nein, nichts geändert


----------



## Sempervivum (28. Juni 2022)

Ich habe noch ein PS geschickt, sieh dir das noch an.


----------



## mstut (28. Juni 2022)

m.scatello hat gesagt.:


> Wie wäre es denn mal mit Fehler selber suchen? Aber Sempervivum kann es ja nicht lassen und schreibt fertige Scripte


Möchtest Du auch die Frage haben?
Kannst Du mir sagen wie eine Kontroll Wechsel Schaltung funktioniert?


----------



## ByeBye 284669 (28. Juni 2022)

mstut hat gesagt.:


> Kannst Du mir sagen wie eine Kontroll Wechsel Schaltung funktioniert?


Nein, kann ich nicht, brauche ich aber auch nicht. Aber wenn würde ich jemanden suchen, den ich für seine Arbeit bezahle


----------



## mstut (28. Juni 2022)

das ist der Inhalt
"116300197353","227.21","201.55","18.037","16.0","2022-01-03 17:03:46"
mfg


----------



## mstut (28. Juni 2022)

m.scatello hat gesagt.:


> Nein, kann ich nicht, brauche ich aber auch nicht. Aber wenn würde ich jemanden suchen, den ich für seine Arbeit bezahle


Das Bedeutet also, wenn du jemanden hir hilft, das er dafür bezahlen muss?


----------



## Sempervivum (28. Juni 2022)

Dann ist alles klar, so kann es dann auch nicht funktionieren. Moment, ich ändere den Code ...


----------



## ByeBye 284669 (28. Juni 2022)

@mstut 
Foren bieten Hilfe zur Selbsthilfe, nicht mehr und nicht weniger. Von Selbsthilfe kann bei dir aber nicht die Rede sein, du machst nur Copy/Paste.
Aber was die Hilfe angeht, gibt es Ausnahmen wie Sempervivum, die den Sinn von Foren extrem ausweiten. Ob das wirklich richtig ist, bezweifele ich allerdings.


----------



## Sempervivum (28. Juni 2022)

Hier ist der geänderte Code, funktioniert mit der Zeile, die Du zuletzt gepostet hast:

```
import sys
import os
import time
import datetime
from csv import reader
import json

try:
    # Intervall in Sekunden für das Prüfen der CSV-Datei:
    intvPoll = 10
    # Anzahl von Datensätzen, die aus der
    # CSV-Datei übernommern werden sollen:
    nrData = 10
    # Intervall in Sekunden, in dem die CSS-Datei
    # aktualisiert wird:
    intvCsv = 600  # 10 Minuten
    # Parameter in der CSV-Datei
    # Schlüssel: Frei wählbarer Name
    # Wert: Der Index in der CSV-Zeile
    confParams = {
        'AIN': 0,
        'Spannung': 1,
        'Leistung': 2,
        'Zaehlerstand': 3,
        'Temperatur': 4,
        'Zeit': 5
        # Datum gelöscht
    }
    # AIN der Steckdose, die gelesen werden soll:
    ainToRead = '116300197353'  # AIN geändert
    # Dateiname der CSV-Datei:
    filenameInCsv = 'DectRead_test.csv'
    filenameOutJson = 'dect-read.json'

    # Ab hier braucht nichts mehr geändert zu werden

    # Zeitraum, innerhalb dessen Daten übernommen werden sollen
    # bzw. maximales Alter der Daten:
    maxAge = nrData * intvCsv
    # Verzeichnis dieser Skriptdatei ermitteln:
    dir = os.path.dirname(os.path.realpath(__file__))
    # Wir gehen davon aus,
    # dass Skript und CSV-Datei im selben Verzeichnis liegen:
    pathIn = dir + '\\' + filenameInCsv
    pathOut = dir + '\\' + filenameOutJson
    # Merker für Zeitstempel:
    tim = 0
    # Endlosschleife:
    while True:
        # Zeit der letzten Änderung der CSV-Datei ermitteln:
        mtime = os.path.getmtime(pathIn)
        # Hat sich die Zeit geändert?
        if(mtime > tim):
            # Neue Zeit merken:
            tim = mtime
            now = datetime.datetime.now()
            # CSV-Datei öffnen:
            with open(pathIn, 'r') as fileIn:
                output = []
                # pass the file object to reader() to get the reader object
                csv_reader = reader(fileIn)
                # Iterate over each row in the csv using reader object
                for row in csv_reader:
                    # row variable is a list that represents a row in csv
                    # print(row)
                    # Zeit für die aktuelle Zeile ermitteln:
                    timeRow = datetime.datetime.strptime(
                        row[confParams['Zeit']], "%Y-%m-%d %H:%M:%S")
                    # Datum heraus genommen, Datum und Uhrzeit sind durch
                    # Leerzeichen getrennt
                    # Alter der Daten ermittteln durch Subtrahieren der Zeit der Zeile
                    # von der Jetzt-Zeit:
                    ageRow = (now - timeRow).total_seconds()
                    # Ist das Alter der Zeile kleiner als das konfigurierte maximale?
                    if ageRow < maxAge:
                        # Gilt die Zeile für die Steckdose, die übertragen werden soll?
                        if row[confParams['AIN']] == ainToRead:
                            # Alle Parameter zum Ausgabe-Array hinzu fügen:
                            params = {}
                            for key in confParams:
                                params[key] = row[confParams[key]]
                            output.append(params)
                # Ausgabe-Array in JSON kodieren:
                with open(pathOut, 'w') as fileOut:
                    fileOut.write(json.dumps(output))
        # Konfigurierte Zeit warten:
        time.sleep(intvPoll)
except:
    print("Error at line", sys.exc_info()[2].tb_lineno, sys.exc_info())
# Zum testen, damit wir die Fehleranzeigen zu Gesicht bekommen:
input()
```


----------



## mstut (28. Juni 2022)

leider wieder schwarzes Bild
und keine json Datei, die hatte ich gelöscht
mfg


----------



## mstut (28. Juni 2022)

m.scatello hat gesagt.:


> Aber was die Hilfe angeht, gibt es Ausnahmen wie Sempervivum, die den Sinn von Foren extrem ausweiten. Ob das wirklich richtig ist, bezweifele ich allerdings.


mein letztes Post dazu
Ich habe niemanden dazu gezwungen mir zu Antworten oder zu helfen
und wenn Sempervivum vorbei kommen würde gibt es Kaffe und Kuchen
und von höflichkeitsregeln hast Du noch nichts gehört, ein Hallo reicht da schon.
mfg


----------



## mstut (28. Juni 2022)

Ich habe mal die CSV verschoben und DR schreibt jetzt eine neue Datei.
Die Original konnte ich nicht mit Libre Office öffnen da zu groß.
jetzt wir auch wieder eine Json geschrieben, aber leer
und wenn ich die CSV im Text Editor öffne sind am Anfang und Ende "
bei Office nicht
mfg


----------



## Sempervivum (28. Juni 2022)

Hast Du die Sache mit der richtigen Zeit berücksichtigt? 100 Minuten in die Vergangenheit.
Für unsere Zwecke ist der Texteditor hier die richtige Wahl. Bei Office, ich nehme an, Du verwendest die Tabellenkalkulation, kann es sein, dass nicht alle Einstellungen passen.


----------



## mstut (28. Juni 2022)

Ich habe Post 9, Link, eine Aktuelle Datei online gestellt


----------



## mstut (28. Juni 2022)

Ich habe gerade gesehen das die Json geschrieben wurde, alles ok


----------



## Sempervivum (28. Juni 2022)

Heißt das, es funktioniert jetzt, JSON mit Daten drin?


----------



## mstut (28. Juni 2022)

ja
kann es sein das die 6 Monate alte zu groß ist?
ich werde sie aber kleiner halten


----------



## mstut (28. Juni 2022)

Wenn ich jetzt die 100 Minuten ändern möcht wie geht das?
kann ich auch mehr als die jetzigen Datenreihen anzeigen?
und was ist intvPoll was bewirkt eine Änderung?
Was ist noch wichtig? ich möchte ja alleine klar kommen.
mfg


----------



## mstut (28. Juni 2022)

Die Anzeige wird immer länger


----------



## Sempervivum (28. Juni 2022)

> Wenn ich jetzt die 100 Minuten ändern möcht wie geht das?


Das geschieht durch diese Variablen:

```
# Anzahl von Datensätzen, die aus der
    # CSV-Datei übernommern werden sollen:
    nrData = 10
    # Intervall in Sekunden, in dem die CSS-Datei
    # aktualisiert wird:
    intvCsv = 600  # 10 Minuten
```

intvCsv ist das Intervall, in dem die Datei aktualisiert wird, d. h. alle 10 Minuten wird für jede Steckdose eine neue Zeile in die Datei geschrieben, wenn ich dich richtig verstanden habe. Diesen Wert brauchst Du nur zu ändern, wenn sich dieses Intervall ändert.

nrData ist die Anzahl der Zeilen, die übernommen werden sollen, je Steckdose. Dies kannst Du beliebig ändern, je nach dem wie viele Zeilen Du haben willst.

Ich habe das Skript extra so angelegt, dass nicht erst alle Zeilen in ein Array eingelesen und dann die letzten verwendet werden, um Ressourcen zu sparen. Du schreibst ja, dass die Datei ziemlich groß werden kann.

Zu intvPoll: Das Skript funktioniert so, dass die CSV-Datei alle 10 Sekunden, das ist der Wert von intvPoll, geprüft wird, ob sich das Änderungsdatum geändert hat. Das bedeutet, dass eine Verzögerung von max. 10 Sekunden auftreten kann bis die JSON-Datei nach einer Änderung der CSV-Datei aktualisiert wird. Verkleinert man den Wert, wird häufiger abgefragt und die Belastung deines PCs erhöht sich. Ich denke aber, dass das nicht ins Gewicht fällt, weil ja nur das Änderungsdatum abgefragt wird und die Datei nicht gelesen wird.


----------



## mstut (28. Juni 2022)

ok, Danke
aber es sind nicht 10 Zeilen ( nrDatei ), siehe Bild Post 58, sondern es werden alle angezeigt.
Bei jeder Aktuallisierung werden es immer mehr.
und so wie ich das sehe, muss die exe aktiv sein.
mfg


----------



## Sempervivum (28. Juni 2022)

Wenn ich mir dein letztes Bild ansehe, wird die Datei jede Minute aktualisiert und nicht alle 10 Minuten. Versuche, den Wert auf 1 zu setzen. Wenn dann die Datei dann immer noch immer größer wird, müssen wir weiter sehen.


----------



## mstut (28. Juni 2022)

ok
Die Daten aus der Steckdose werden je 1 Minute ausgelesen
meine HP Daten aber alle 10 Minuten Aktuallisiert
Da habe ich mich woh falsch ausgedrückt.
Sorry


----------



## Sempervivum (28. Juni 2022)

Ah, verstehe. Dann müsste es eigentlich funktionieren, wenn Du den Wert auf 1 setzt.


----------



## mstut (28. Juni 2022)

Ich kopiere im Moment zum Test die Datei vom Wetter PC auf meinen PC
ich dacht, das es immer die letzten xx Datensätze sind


----------



## Sempervivum (28. Juni 2022)

Nein, ich habe es auf die Zeit bezogen und zwar wegen des Gesichtspunktes des Ressourcenbedarfs. Und ich erwarte, wenn das ganze dann kontinuierlich läuft, es auch funktionieren wird wie gewünscht.


----------



## mstut (28. Juni 2022)

ok, also wenn ich einfach so kopiere passt die Zeit nicht
aktuell ist in der Anzeige von 18:36 bis 19:54


----------



## mstut (28. Juni 2022)

Ich glaube das ist anders
ich hätte gerne die letzten 10 oder x Datensätze
wenn jetzt die Aktuallisierung der HP alle 10 Minuten erfolgt
dann müsten 10 Datensätze ausgelesen werden und bei 20 Minuten auch nur 10 Datensätze
es kann ja auch mal sein das es ein Problem gibt und ich das erst ein mal beheben muss, PC Absturz


----------



## mstut (28. Juni 2022)

ich bin den für heute weg
schönen Abend noch


----------



## Zvoni (29. Juni 2022)

Und das ganze rumgeturne ist "einfacher" als ne SQLite oder MySQL-DB per Query auszulesen?


----------



## ByeBye 284669 (29. Juni 2022)

Zvoni hat gesagt.:


> Und das ganze rumgeturne ist "einfacher" als ne SQLite oder MySQL-DB per Query auszulesen?


Nein, aber das scheint ja keine Rolle zu spielen.   Warum einfach, wenn es auch komplizierter geht.


----------



## mstut (29. Juni 2022)

Hallo

Funktioniert einwandfrei
bei nrDate =1 - 10 Reihen, bei 2 - 20 Reihen usw.
ich möcht die dect-read.json auf eine ander Festpaltte speichern.
Ich habe schon probiert, habe ea aber nicht hin bekommen.

mfg
Michael


----------



## Sempervivum (29. Juni 2022)

Was ist denn der Grund dafür? Wird von der anderen FP aus zur Website übertragen?
Wir können problemlos einen vollständigen Pfad für die Ausgabedatei angeben:

```
import sys
import os
import time
import datetime
from csv import reader
import json

try:
    # Intervall in Sekunden für das Prüfen der CSV-Datei:
    intvPoll = 10
    # Anzahl von Datensätzen, die aus der
    # CSV-Datei übernommern werden sollen:
    nrData = 10
    # Intervall in Sekunden, in dem die CSS-Datei
    # aktualisiert wird:
    intvCsv = 600  # 10 Minuten
    # Parameter in der CSV-Datei
    # Schlüssel: Frei wählbarer Name
    # Wert: Der Index in der CSV-Zeile
    confParams = {
        'AIN': 0,
        'Spannung': 1,
        'Leistung': 2,
        'Zaehlerstand': 3,
        'Temperatur': 4,
        'Zeit': 5
        # Datum gelöscht
    }
    # AIN der Steckdose, die gelesen werden soll:
    ainToRead = '116300197353'  # AIN geändert
    # Dateiname der CSV-Datei:
    filenameInCsv = 'DectRead_test.csv'
    # Vollständiger Pfad der Ausgabedatei:
    filenameOutJson = r'F:\dein-pfad\dect-read.json'

    # Ab hier braucht nichts mehr geändert zu werden

    # Zeitraum, innerhalb dessen Daten übernommen werden sollen
    # bzw. maximales Alter der Daten:
    maxAge = nrData * intvCsv
    # Verzeichnis dieser Skriptdatei ermitteln:
    dir = os.path.dirname(os.path.realpath(__file__))
    # Wir gehen davon aus,
    # dass Skript und CSV-Datei im selben Verzeichnis liegen:
    pathIn = dir + '\\' + filenameInCsv

    # Vollständigen Pfad für die Ausgabe definieren
    # Da filenameOutJson schon vollständig ist brauche wir ihn
    # pathOut nur zuzuweisen:
    # pathOut = dir + '\\' + filenameOutJson
    pathOut = filenameOutJson
    # Merker für Zeitstempel:
    tim = 0
    # Endlosschleife:
    while True:
    
    # das Folgende wie bisher
```


----------



## mstut (29. Juni 2022)

Hallo

Ja, DR läuft auf einer andern Partition und die Übertragung ist aus C:
Mein Fehler war das r 

```
filenameOutJson = r'C:\Wswin\html\csv\dect-read.json'
```
leider Fehlermeldung Line 84

mfg
Michael


----------



## mstut (29. Juni 2022)

Hallo
Sind vielleicht keine Schreibrechte vorhanden.
Kopiere die Datei alle 10 Minuten in den Ordner.
Testseite
mfg
Michael


----------



## Sempervivum (29. Juni 2022)

Was steht denn in Zeile 84 und wie lautet die Fehlermeldung?
Und was sagt mir die Testseite? Wenn es sich um die HTML-Tabelle aus dem JSON handelt hieße das, es funktioniert?


----------



## mstut (29. Juni 2022)

> # Ausgabe-Array in JSON kodieren:
> with open(pathOut, 'w') as fileOut:


Zeile 84
so wie in Post 73 geht es nicht
ich erstelle die Datei jetzt im gleichen Ordner wie die import sys und Kopiere die json in den C: Ordner
so funktieniert es im Moment.
mfg


----------



## Sempervivum (29. Juni 2022)

Geht nicht gibt's nicht. Wenn beim Öffnen der Datei schon ein Fehler auftritt, findet er den Pfad nicht.
Überprüfe das, indem Du den Pfad ausgeben lässt:

```
# Ausgabe-Array in JSON kodieren:
print(pathOut)
with open(pathOut, 'w') as fileOut:
```


----------



## mstut (29. Juni 2022)

Ich habe nicht aufgepasst
Ich hatte nur den Link und nicht den Geposteten Tei mit eingefügt
Teste ich nachher
mfg


----------



## Sempervivum (29. Juni 2022)

Hatte ich mir fast schon gedacht, ich denke, anschließend wird es funktionieren.


----------



## mstut (29. Juni 2022)

So, hat etwas länger gedauert.
Da hatte sich doch ganz unten ein Text den ich kopiert hatte eingeschlichen und den hatte ich nicht gleich gefunden.
Es läuft jetzt und die Testseite ist erst ein mal als Kontrolle für mich.
So kann ich Tags über immer mal schauen.
Noch mals vielen Dank für deine Hilfe.

mfg
Michael


----------



## mstut (2. Juli 2022)

Hallo
Die Anzeige ist jetzt auf meiner HP zu sehen.
Und das ganze ohne Hilfe !
mfg
Michael


----------



## ByeBye 284669 (2. Juli 2022)

mstut hat gesagt.:


> Und das ganze ohne Hilfe !


Dein Ernst? Und was ist mit den rund 30 Postings von Sempervivum, in denen er dir auch noch ein Script geschrieben hat? Ohne Hilfe hättest du das bestimmt nicht auf deiner HP.


----------



## mstut (2. Juli 2022)

Hallo

Irgen wie kannst Du das Sticheln nicht lasen.
Ja, er hat mir geholfen und genau dafür ist ein Forum da.
Mal gibt es viel Hilfe und mal wenig.
Du hast ja nicht geholfen.
Sempervivum hat zwar ein Beispiel gezeigt, wie die Ausgabe sein kann,
das was ich aber daraus gemacht habe ist ganz anderes Aufgebaut und war für mich nicht einfach.
Du schreibst es in 10 Minuten und ich in ein Paar Stunden.
Aber egal, das Ergebniss zählt.
Nun viele Spaß beim Negativ schreiben, das hilft allen anderen die hier mitlesen.

mfg
Michael


----------

