# CSV-Datei auslesen und über MQTT verschicken



## BaumimGarten (9 November 2021)

Hallo Leute,

Ich arbeite gerade daran, erzeugte Werte von der SPS über Mqtt zu meinen Broker (Thingsboard) zuschicken. Gleichzeitig soll bei einem Zwischenpuffer alle Daten gespeichert werden. Von diesem Zwischenspeicher soll dann ein Zeiger Zeilenweise die Daten auslesen und an den MQTT Baustein weiterliefern. Bei Verbindungsabbruch, sollen weiterhin die Werte gespeichert werden, aber der Zeiger soll bei dem zuletzt übergebenden Wert stoppen und erst bei erneuter Verbindung weiter Werte überliefern.

Die Datenspeicherung in eine CSV Datei hab ich hinbekommen, sowie das Übermitteln über MQTT von einzelnen Werten aus einer Variable. Allerdings habe ich direkt die Werte übermittelt und diese nicht aus einer CSV Datei gelesen. Ebenfalls weiß ich nicht so ganz wie ich das mit dem Zeiger machen soll.

Die Frage ist mit welchem Baustein arbeite ich am besten um die Werte aus der CSV Datei auszulesen, da ich mit dem MQTT Baustein nur ein Array of Bytes übergeben kann. Den Verbindungsabbruch kann ich ja über eine Case Funktion gut beschreiben, brauche aber dazu ja auch eine Laufvariable die die einzelnen Zeilen der CSV Datei durchgeht.

Ich hoffe ich hab mein Anliegen einigermaßen verständlich rübergebracht und danke für jede Form von Hilfe


----------



## Gerhard Bäurle (9 November 2021)

BaumimGarten schrieb:


> Ich hoffe ich hab mein Anliegen einigermaßen verständlich rübergebracht und danke für jede Form von Hilfe


Hallo, ich habe nicht wirklich was verstanden, aber das bedeutet ja nichts 

Fragen: Welche SPS, welches Systems schreibt die CSV und wo läuft der MQTT-Baustein?

Nebenbei: Thingboard sehe ich nicht als Broker, der nur Daten verschiebt – sondern eher ein Analyse-Plattform als Cloud-Anwendung, welche die Daten auswerten, verarbeiten und visualisieren kann.


----------



## BaumimGarten (9 November 2021)

Hi, danke für die schnelle Antwort.

Ich arbeite mit einer S7-1511T-1 PN und Tia 17 von der Arbeit, 
die CSV Datei wird über die Bausteine "DataLogCreat" und "DataLogWrite" erstellt und beschrieben,
der MQTT-Baustein läuft über mein TIA und soll wie gesagt die Daten nicht aus einer Variable schicken, sondern über die eingelesene CSV Datei schicken


----------



## Thomas_v2.1 (9 November 2021)

Am Einfachsten dürfte es doch sein, die Daten nicht ins Datalog zu schreiben, und da auszulesen, sondern erst im Speicher der SPS ablegen (Datenbaustein), dann per MQTT verschicken und wenn es dann noch notwendig ist für welche Zwecke auch immer aufs Datalog auszulagern und den Datenbaustein freimachen.

Denn auch wenn du aus dem Datalog zurücklesen könntest, bräuchtest du ja trotzdem Platz in einem Datenbaustein für den Inhalt. Außer es würde dort Zeilenweise funktionieren.


----------



## BaumimGarten (10 November 2021)

Thomas_v2.1 schrieb:


> Am Einfachsten dürfte es doch sein, die Daten nicht ins Datalog zu schreiben, und da auszulesen, sondern erst im Speicher der SPS ablegen (Datenbaustein), dann per MQTT verschicken und wenn es dann noch notwendig ist für welche Zwecke auch immer aufs Datalog auszulagern und den Datenbaustein freimachen.
> 
> Denn auch wenn du aus dem Datalog zurücklesen könntest, bräuchtest du ja trotzdem Platz in einem Datenbaustein für den Inhalt. Außer es würde dort Zeilenweise funktionieren.


Mit Datenbaustein meinst du bestimmt ein Array zum ablegen oder ? 
Das Problem vordem ich stehe ist halt, wenn die SPS plus Datenlieferant in einer mobilen Station Daten liefern soll und dann in ein Funkloch gerät. Dann ist die Verbindung zum MQTT kurzzeitig unterbrochen, es sollen allerdings weiter Daten ermittelt und aufgezeichnet werden, die dann bei Wiederverbindung an dem letzten übertragenden Datenpunkt (im Array oder CSV Datei) weiter an den MQTT überträgt. Die in dem Zeitfenster des Verbindungsabbruches erstellten Werte, sollen (mit Zeitstempel) Zeile für Zeile nach geliefert werden, bis die Überlieferung wieder auf dem aktuellen stand ist. 

Ich wüsste nicht wie ich das alles für einen unbestimmten Zeitraum in ein Array speichern soll (also wüsste ich schon allerdings weiß ich ja nicht wie der Verbindungsabbruch sein kann und somit nicht die Länge meines Arrays anpassen kann ohne es mit 99999 Zeilen zu bestücken). Ebenfalls wäre dann meine frage wie ich dann die Datenpunkte mit einem aktuellen Zeitstempel versehe.


----------



## Thomas_v2.1 (10 November 2021)

Deine CSV Datei kann aber auch nicht unendlich groß werden. Du musst vorher definieren welchen Zeitraum du überbrücken willst, und dann entsprechend auslegen. Z.B. zwei Tage puffern, Aufzeichnungsintervall 1 Minute = 60 * 24 * 2 = 2880 Werte. Wenn du das als Ringpuffer organisierst in dem die Werte im gleichen Intervall abgelegt wurden, dann brauchst du nur den Zeitstempel vom aktuellen Wert und kannst daraus auf die Zeitstempel der vorigen Werte schließen. Wenn du genug Speicher zur Verfügung hast dann kannst du natürlich auch den Zeitstempel mit ablegen. Dafür gibt es eine eigene Funktion in der Bibliothek, um die Systemzeit oder die Lokalzeit zu lesen, diese speicherst du dann mit ab, z.B. als Array of Struct (Real, Timestamp).


----------



## PN/DP (10 November 2021)

BaumimGarten schrieb:


> Ebenfalls wäre dann meine frage wie ich dann die Datenpunkte mit einem aktuellen Zeitstempel versehe.


Falls der Empfänger den Datensätzen den Empfangszeitpunkt als Zeitstempel verpasst, dann sieht das mit korrektem Zeitstempel beim Nachreichen von Datensätzen eher schlecht aus.

Harald


----------



## BaumimGarten (10 November 2021)

Den Zeitstempel der Abspeicherung kann ich bei dem Baustein für den DataLog (also für das schreiben in den CSV) direkt mit angeben also wenn man tatsächlich die CSV Datei auslesen kann würde glaub ich der Char bzw. die Bytes auch diesen auch richtig anzeigen. Allerdings hapert es ja daran die CSV auszulesen. 
Ich hab jetzt ein okayisch Ergebnis. 
Ich hab jetzt anstatt eine CSV Datei eine txt. Datei geschrieben und da meine lesegrenzen so auf die Schreiblänge des geschriebenen Wertes angepasst und zähle mein schreib- und leseoffset, einmal mit dem fertigen beschreiben der Datei, sowie das fertigen senden der Daten an den Mqtt hoch. 
Ist zwar echt nicht das schönste Programm aber funktioniert.


----------



## Thomas_v2.1 (10 November 2021)

Und nur wenn die Datei eine andere Endung hat, kannst du diese vom SPS-Programm aus einlesen? Mit welcher Funktion?


----------



## BaumimGarten (11 November 2021)

Ich hab das jetzt mit dem Funktionsblock "FileWriteC" und "FileReadC" gemacht. Als ich versucht hatte über den Read Baustein die vorher schon erstellte CSV Datei auszulesen hat er mir immer die Fehlermeldung von "Pfad nicht gefunden". Entweder war ich dazu zu unfähig den richtigen Pfad anzulegen (was ich für unwahrscheinlich, aber nicht unmöglich halte) oder er hat sich schwer getan den DataLog auszulesen oder der Baustein konnte generell nichts mit der CSV Datei anfangen.


----------

