Hallo nochmal,
einen bzw. zwei Logeinträge hab ich noch die ich gerne nicht mehr hätte, mir nicht zu helfen weiß.
Es steht zwar Fehler im Log, setreading inot_Umsatz umsatzmtl $umsatzmtl wird aber korrekt ausgeführt, also es klappt alles wie es soll.
Bin eigentlich der Meinung alles wie bei meiner alten Installation gemacht zu haben, da hatte ich das nicht.
defmod inot_Umsatz inotify /tmp UMFHEM.*
attr inot_Umsatz fhem_widget_channels [{"alias":"Umsatz","order":1,"allowed_values":[],"controlled_attribute":"STATE"}]
attr inot_Umsatz mask IN_ATTRIB
attr inot_Umsatz room Büro,Fhem_Widget
attr inot_Umsatz stateFormat umsatzmtl €
setstate inot_Umsatz xxxxxx,xx €
setstate inot_Umsatz 2019-09-24 11:44:37 lastEventFile /tmp/UMFHEM.csv
setstate inot_Umsatz 2019-09-24 11:44:37 lastEventMask IN_ATTRIB
setstate inot_Umsatz 2019-09-24 11:44:37 umsatzmtl xxxxxx,xx
defmod not_inot_Umsatz notify inot_Umsatz:lastEventFile:.* { my $umsatzmtl = readCSV("/tmp/UMFHEM.csv","Umsatz");;;;\
{fhem ("setreading inot_Umsatz umsatzmtl $umsatzmtl")}}
attr not_inot_Umsatz room Büro
setstate not_inot_Umsatz 2019-09-24 11:44:37
setstate not_inot_Umsatz 2019-09-22 20:53:42 state active
2019.09.24 11:44:37 1: ERROR evaluating my $EVTPART1='/tmp/UMFHEM.csv';my $EVENT='lastEventFile: /tmp/UMFHEM.csv';my $TYPE='inotify';my $SELF='not_inot_Umsatz';my $NAME='inot_Umsatz';my $EVTPART0='lastEventFile:';{ my $umsatzmtl = readCSV("/tmp/UMFHEM.csv","Umsatz");;
{fhem ("setreading inot_Umsatz umsatzmtl $umsatzmtl")}}: 2012EOF - End of data in parsing input stream010 at /usr/local/share/perl/5.24.1/Text/CSV/Slurp.pm line 101.
2019.09.24 11:44:37 3: not_inot_Umsatz return value: 2012EOF - End of data in parsing input stream010 at /usr/local/share/perl/5.24.1/Text/CSV/Slurp.pm line 101.
##################################################################
# Routine zum Einlesen einer CSV-Datei
#!/usr/bin/perl
package main;
use strict;
use warnings;
use POSIX;
use strict;
use warnings;
use Text::CSV::Slurp;
sub myUtilsCSV_Initialize($$)
{
my ($hash) = @_;
}
####################################################################
sub readCSV ($$)
{
my ($csvDatei, $Spalte) = @_;
my $slurp = Text::CSV::Slurp->new();
my $Wert;
my $Datum;
# CSV Options - see Text::CSV
my %csv_options = (
sep_char => ';',
binary => '1',
);
# Reference to an array of hashes
my $data = $slurp->load( file => $csvDatei, %csv_options );
foreach my $row (@$data) {
$Wert = $row->{$Spalte};
}
return $Wert
}
1;
Der Inhalt der CSV-Datei
"Monat";"Umsatz"
"September 2019";xxxxxx,xx
Gruß
Thomas
In Zeile 101 der Slurp.pm steht der else-Zweig folgender Funktion :
91 sub _from_handle {
92 my $io = shift;
.. my $opt = shift;
..
.. my $csv = Text::CSV->new($opt);
..
.. if ( my $head = $csv->getline($io) ) {
.. $csv->column_names( $head );
.. }
.. else {
101 die $csv->error_diag();
102 }
Kann jemand mit der Info sagen, was der mögliche Grund für die Fehlermeldung ist ?
Gruß
Thomas
Hallo Thomas,
ich habe keine Ahnung, finde interessant das es sowas gibt (CSV Import) ;)
Beim Googeln nach der Fehlernummer 2012EOF habe ich Hinweise gefunden, dass slurp nur Zeichen 20-7F akzeptiert und deshalb eventuell das Dateiende EOF nicht erkennt.
Wo September da auch März? Das ä wäre außerhalb von 20-7F
Also nur ein Vermutung...
Gruß Otto
Hier (https://waschto.eu/csv-datei-als-fhem-reading-einlesen/) hab ich das her, würd mich wundern das du den Beitrag nicht kennst.
Wie gesagt, auf meiner alten Installation hatte ich den Logeintrag nicht und da lief das rund 1 1/2 Jahre, deshalb schliesse ich mal
ZitatWo September da auch März? Das ä wäre außerhalb von 20-7F
vorsichtig aus.
Gruß
Thomas
Muss mich korrigieren. Sry.
Hab mir mittlerweile LogFiles meiner alten Installation angeschaut, damals hatte ich die Log-Einträge auch.
Die UMFHEM.csv Datei exportiere ich aus einer Access2000-Datenbank :P via VBA in den Ordner /tmp , nur dann hab ich den Fehler im Log.
Bearbeite ich die Datei händisch gibt es keine Meldungen im Log.
Sollte jemand weiterhelfen können wie ich den Fehler im Log vermeiden könnte mit folgendem DoCmd-Objekt hab ich das exportieren umgesetzt:
DoCmd.TransferText acExportDelim, "UMFHEM-Exportspezi", _
"qry_UMFHEM", "\\192.168.188.26\Raspi3tmp\UMFHEM.csv", True
Gruß
Thomas
Hallo Thomas,
mal versucht die CSV Datei ins Unix Text Format zu konvertieren? Windows hat 0D 0A als Zeilenumbruch Unix nur 0A. (CR LF | \r \n)
Gruß Otto
Hallo Otto,
musste mich auch erstmal wieder eindenken, die Parameter für das konvertieren gibt man in einer Exportspezifikation (hier die UMFHEM-Exportspezi) an und in der war tatsächlich Westeuropäisch (Windows) angegeben. Das hab ich jetzt geändert in Unicode (UTF-8), es bleibt aber bei der Meldung im Log.
Eine andere Sprache einzustellen ist irgendwie nicht möglich, da kommt dann gleich ein Popup-Fenster: Die Einstellung für diese Eigenschaft ist zu lang
Gruß
Thomas
Moin,
na Zeichensatz ist das Eine, Zeilenumbruch ist etwas anderes. Windows schreibt CR LF und die meisten Linux Programme kommen damit nicht zurecht.
Gruß Otto
In anderen Worten es bleibt bloß ein verbose 0 im notify und inotify ?
Du verstehst mich nicht, hast Du die Datei mal von den Windows Zeilenumbrüchen befreit? Das ist doch absolut easy?
Ich dachte ich habe das schon geschrieben: dos2unix oder im notepadd++ und rechts mit der rechten Maustaste konvertieren oder tr -d '\r'
Ja ich komm irgendwie nicht mit, was bringt mir das wenn ich händisch die Datei ändere und es dann klappt.
Die Datei wird doch immer wieder neu exportiert, manchmal mehrmals am Tag, manchmal gar nicht, ich muss doch schauen das die Zeilenumbrüche erst gar nicht exportiert werden.
Was es Dir bringt? Du bist ein Witzbold :) Dann wüsstest Du die Ursache und man könnte etwas in Deine Importroutine einbauen ::)
Wenn Du am export nichts machen kannst - dann bleibt Dir der Import, den hast "Du" doch gemacht :)
Versuch macht kluch :)
Also mAn liegts nicht an dem CR LF.
Ich kann die Datei UMFHEM.csv mit Notepad++ öffnen, unten rechts sieht man das der Windows (CR LF) Zeilenumbruch verwendet wird, den Umsatz bearbeiten, ohne weitere Änderungen speichern, das inotify reagiert und es gibt keinen Log-Eintrag.
Weitere Feststellung. Speichere ich die Datei in Notepad++ mit der Angabe UNIX (LF) kann ich genau einmal exportieren und es kommt kein Log-Eintrag, beim zweiten exportieren ist er wieder da.
Also liegts wsl. doch an dem CR LF.
Das verwirrt mich jetzt, Du redest vom exportieren....
Du meinst importieren in FHEM?
Also wenn die Erkenntnis ist: mit LF gibt es keinen Log Eintrag mit CR LF gibt es einen bedeutet das man muss vor dem Einlesen die Datei vom CR befreien.
Ich habe keine schnelle Lösung weil deine Importroutine aus meiner Sicht für 2 Werte importieren ziemlich komplex ist :)
Eigentlich müsste man einfach die Originaldatei nehmen. Eine Zeile shell code
cat original.csv|tr -d '\r' > kopie.csv
und statt der original.csv die kopie.csv einlesen.
Deine Datei hat wirklich immer bloß 2 Werte?
Gruß Otto
Ja ich rede vom exportieren aus Access heraus. Für die Datei hab ich extra eine Abfrage erstellt die nur diese zwei Werte hat, diese wird bei bestimmten Aktionen ( bspw. beim schliessen der Seitenansicht ) als .csv exportiert.
Diesen Weg (Export aus Access über die Importroutine) hatte ich damals gewählt um automatisiert den Wert in FHEM zu bekommen und ich keinen anderen Weg wusste.
Ich versuche gerade die Doku (https://metacpan.org/pod/Text::CSV#eol) zu verstehen, sollte es danach nicht egal sein welcher Zeilenumbruch verwendet wird ?
Beim schreiben kommt mir gerade das es doch auch mit FileRead gehen muss ::), einfach die Abfrage (in Access) anpassen das nur noch der gewünschte Wert drin steht und einlesen, fertig. Da muss ich mich jetzt einlesen, dann wäre die Importroutine für diesen Zweck schnell gegessen ;D
Das mit fileread sehe ich auch so!
Die Doku die Du da hast hat doch nichts mit slurp zu tun ? Ach so doch weil die dann TEXT:CSV benutzen. Ich habe keine Ahnung wer jetzt stolpert. Ich war durch die Beschreibung (eine Beschreibung?) von slurp darauf gekommen, dass ein Zeichen stört. War nur ne Idee von mir, ich habe manchmal solche "Queransätze" :)
Vielleicht ist es auch nicht der Zeilenwechsel, sondern ein komisches Zeichen am Ende der Datei was Access daheinzaubert?
Also die Importroutine ist Geschichte für diesen Anwendungsfall. 8)
Am Export (aus Access) der Datei hab ich gar nichts geändert.
Das notify sieht jetzt so aus und funzt, keine Logmeldungen:
defmod not_inot_Umsatz notify inot_Umsatz:lastEventFile:.* { my ($error, @content) = FileRead({FileName => "/tmp/UMFHEM.csv", ForceType => "file"});;;;$content[1]=~ s/.*;;//;;;;\
{fhem ("setreading inot_Umsatz umsatzmtl $content[1]")}}
Spricht was dagegen es so zu machen.
Gruß
Thomas
Das bedeutet: eigentlich brauchst Du aus der Datei nur den einen Wert Umsatz. Die Tabellenköpfe (1.Zeile) und das Datum ignorierst Du.
Klar dann geht das so.
Du kannst die vierer Bande ;;;; noch halbieren (nicht die zweier ;; !)
Ich überlege nachher nochmal, geht vielleicht sogar noch kürzer mit set magic
Also den Code quasi "umdrehen" - erstmal ungetestet:
Edit/Korrektur:
In der Kommandozeile
setreading inot_Umsatz umsatzmtl {(my ($error, @content) = FileRead({FileName => "/tmp/UMFHEM.csv", ForceType => "file"});;$content[1]=~ s/.*;;//;;return $content[1])}
In der Raw Definition müssen die ; nochmal verdoppelt werden - siehe Beitrag unten (https://forum.fhem.de/index.php/topic,103975.msg979069.html#msg979069).
defmod not_inot_Umsatz notify inot_Umsatz:lastEventFile:.* setreading inot_Umsatz umsatzmtl {(my ($error, @content) = FileRead({FileName => "/tmp/UMFHEM.csv", ForceType => "file"});;;;$content[1]=~ s/.*;;;;//;;;;return $content[1])}
Du kannst die vierer Bande ;;;; noch halbieren (nicht die zweier ;; !)
Raw Definition ! ! !
ich weiß, aber man braucht nur verdoppeln nicht vervierfachen.
Hab doppelte in der DEF und in der Raw Definition sinds 4, komm ich nicht mit, darfs auch nur eins sein in der DEF ?
In der DEF braucht man an der Stelle eins um Befehle zu trennen.
Hab den Code oben getestet und geändert. Funktioniert :)
Wenn es schöner sein soll, packst Du die Zeile Code in drei Zeilen in die 99_myUtils und im setreading steht dann einfach {NameDerSub}
Hallo Otto,
die kürzere Variante funzt bei mir so nicht es gibt wieder zwei Log-Meldungen:
defmod not_inot_Umsatz notify inot_Umsatz:lastEventFile:.* setreading inot_Umsatz umsatzmtl {(my ($error, @content) = FileRead({FileName => "/tmp/UMFHEM.csv", ForceType => "file"});;$content[1]=~ s/.*;;//;;return $content[1])}
Zitat2019.09.29 13:50:39 3: not_inot_Umsatz return value: Unknown command $content[1]=~, try help.
Unknown command //, try help.
Unknown command return, try help.
2019.09.29 13:50:39 3: not_inot_Umsatz return value: Unknown command $content[1]=~, try help.
Unknown command //, try help.
Unknown command return, try help.
Es müssen jetzt (in der Raw Definition) vierer Banden sein, auch die in der regex, funzt und keine Log-Meldungen:
defmod not_inot_Umsatz notify inot_Umsatz:lastEventFile:.* setreading inot_Umsatz umsatzmtl {(my ($error, @content) = FileRead({FileName => "/tmp/UMFHEM.csv", ForceType => "file"});;;;$content[1]=~ s/.*;;;;//;;;;return $content[1])}
Gruß
Thomas
Und ich dachte ich hatte es mittlerweile mal verstanden :-[ ??? :'(
Im define müssen die ; verdoppelt werden.
In der Kommandozeile müssen die ; verdoppelt werde.
Ich habe den Code in der Kommandozeile getestet. Also mit ;;
Alles klar: Das setreading ....{} ist von der Sache her wieder eine Kommandozeile. Braucht also ;; (doppelt)
Deswegen brauchst Du define alles doppelt doppelt ;;;;
Und ich habe meinen getesteten Code (Kommandozeile) einfach in dein defmod kopiert und nicht nochmal getestet. Sorry. Ich korrigiere das oben!
Gruß Otto
Hallo Thomas,
noch so eine Idee - wenn es mal nix mehr zu tun gibt :) :
Man kann auch über Powershell direkt in FHEM Readings beschreiben. Ich habe nicht viel Ahnung von Access aber ich bin mir sicher:
Man kann irgendwie ein Powershell Script aus Access heraus starten und Parameter (Umsatz) übergeben.
Man kann aus Powershell auf eine Access Datenbank zugreifen.
Also je nach dem wie dein Prozess mit dem Export / Import ist -> man braucht da eventuell den Umweg über die Datei nicht und kann es einfacher / direkter machen.
Grüße Otto