DOIF perl System Befehl mit einer Globalen Variable

Begonnen von Stelaku, 03 November 2022, 20:33:57

Vorheriges Thema - Nächstes Thema

Stelaku

Hallo alle zusammen

Ich bastel gerade an einen kleinen DOIF im perl Mode und komme nicht weiter. Das DOIF soll einfach nur die fhem.cfg und die fhem.save datei in einem Verzeichnis speichern um bei bedarf
diese wieder zurück zu schreiben.
hier ein raw des DOIF
defmod save DOIF {\
if ([global:"^SAVE$"]) {\
my $now = ::strftime "%d.%m.%Y-%H.%M.%S",localtime();;\
set_State($now);;\
system("mkdir -p save/$now");;\
system("mkdir -p save/$now/log");;\
system("cp $attr{global}{configfile} ./save/$now/fhem.cfg");;\
system("cp $attr{global}{statefile} ./save/$now/log/fhem.save");;\
}\
}

es funktioniert in grunde genommen auch, ich stolpere nur über die beiden system Befehle
system("cp $attr{global}{configfile} ./save/$now/fhem.cfg");
system("cp $attr{global}{statefile} ./save/$now/log/fhem.save");

die bescheren mir eine Fehlermeldung
ondition c01: Global symbol "%attr" requires explicit package name (did you forget to declare "my %attr"?) at (eval 1700) line 7.
Execution of (eval 1700) aborted due to compilation errors.


wenn ich $attr{global}{configfile} hart codiere und einfach fhem.cfg schreibe oder für den zweiten system Befehl ./log/fhem.save
funktioniert das DOIF.
in der komandozeile funktionieren  die beiden Aufrufe
{$attr{global}{statefile}}
damit bekomme ich die gewünschte Rückgabe des Pfad zu der Datei fhem.save
auch etliche Versuche mit geschweiften Klammern und runden Klammern führten zu keinen Erfolg.
Würde mich freuen wenn einer noch eine Idee hat.

Viele Grüße

Stephan

Otto123

Hallo Stephan,

ein notify hat das Problem mit deinem Code nicht :)
defmod global_notify_1 notify global:SAVE {my $now = strftime "%d.%m.%Y-%H.%M.%S",localtime();;\
fhem("setreading $SELF now $now");;\
system("mkdir -p save/$now");;\
system("mkdir -p save/$now/log");;\
system("cp $attr{global}{configfile} ./save/$now/fhem.cfg");;\
system("cp $attr{global}{statefile} ./save/$now/log/fhem.save");;\
return undef}


Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Stelaku

#2
Hallo Otto

Vielen dank für Deine Antwort. Ich habe die Idee aus diesem Thread übernommen in dem
das ganze auch in einen notify prima funktioniert.
https://forum.fhem.de/index.php/topic,104672.msg985683.html#msg985683
Aber aus Deinem Beispiel übernehme ich doch glatt mkdir -p den Schalter kannte ich noch nicht.
Keine Fehlermeldung wenn Verzeichnis schon vorhanden. Sehr schön wieder was gelernt.


Mir geht es auch darum das beim vorhandenen restore save immer nur der letzte save eines Tages gespeichert wird.
Und ich wollte das gerne in einen DOIF umsetzten damit ich noch mehrere Funktionen in einen
Device habe. Das DOIF ist ja noch nicht fertig. Es sollen noch Funktionen eingebaut werden wie z.b. das
zurückspielen der Gespeicherten Dateien usw.

Viele Grüße

Stephan

Damian

Im Perl-Modus bist du im DOIF-Package. $attr dürfte in main sein, daher:

$::attr{global}{configfile}

angeben.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Stelaku

Hallo Damian

klasse damit funktioniert es.
Vielen dank für Deine hilfe.

Viele Grüße

Stephan

Stelaku

#5
Hallo Damian

Mein kleines DOIF ist fertig und funktioniert prima.
defmod save DOIF subs{\
sub speichern{\
my $now = ::strftime "%d.%m.%Y-%H.%M.%S",localtime();;\
system("mkdir -p save/$now");;\
system("mkdir -p save/$now/log");;\
system("cp $::attr{global}{configfile} ./save/$now/fhem.cfg");;\
system("cp $::attr{global}{statefile} ./save/$now/log/fhem.save");;\
$_max = get_Reading("Max");;\
$_ist = qx "ls -A1 save/ | wc -l";;\
$_loeschen = $_ist - $_max;;\
if ($_loeschen > 0) {\
qx "ls -dt1 save/*|tail -$_loeschen| xargs rm -r";;\
}\
if ($_loeschen <1 ){\
set_State("es wurde kein Speicherstand gelöscht Max $_max noch nicht erreicht");;\
}\
else{\
set_State("$_loeschen alter Speicherstand wurde gelöscht");; \
}\
$_gespeichert = qx "ls -a save";;\
set_Reading("speicherstand",$_gespeichert,0);;\
}\
}\
speichern\
{\
if ([global:"^SAVE$"]) {\
set_Exec("verz","2",'speichern()');;\
}\
}\
restore\
{\
if ([$SELF:"^Zurueck.*$"]){\
$_event=(split' ', $event)[1];; \
system("cp -r ./save/$_event/* /opt/fhem/");;\
set_State ("$_event wurde zurückgeschrieben");; \
set_Exec("verz","2",'fhem("shutdown restart")');;\
}\
}
attr save readingList Max
attr save room system
attr save setList Max:textField\
Zurueck:textField
setstate save 2022-11-06 09:45:28 Max 10


hiermit ist es jetzt möglich unter den reading Max anzugeben wieviele Speichstände man Maximal gespeichert haben möchte und es wird wenn die Max Zahl erreicht wird der älteste
Speicherstand gelöscht.
Will man jetzt auf einen älteren Speicherstand zurück braucht man nur das Datum des Speicherstandes im Reading Speichstand kpl. makieren und Kopieren.
Dann dieses über set save Zurueck eintrangen und set klicken.
Und schon ist man auf einen alten Speichstand.
Das ganze habe ich dann noch über menü entries leicht zugänglich gemacht so das ich es ohne grosses suchen auf der linken Seite schnell anklicken kann.

attr WEB menuEntries restore save,/fhem?detail=save,


Eine kleine Frage hätte ich da jetzt aber noch.
Ganz zum Schluss lasse ich Fhem über ein shutdown restart neu starten. Das funktioniert auch ohne Probleme.
Ursprünglich hatte ich da aber ein rereadcfg drin. das führte dann dazu das Fhem beim hochfahren plötzlich blockierte weil ein
sleep Befehl angeblich ohne ein set Befehl ausgeführt wurde. Meldung im log
2022.11.06 09:28:14 1: WARNING: sleep without additional commands is deprecated and blocks FHEM
diese Meldung wurde durch ein sleep aus einen DOIF verursacht in dem ich ein sleep im attr startup habe. hier eine test device
defmod sleeptest DOIF ([platz])()
attr sleeptest startup setreading $SELF Fhem startet;;sleep 20;;set $SELF cmd_1


ist das so richtig oder habe ich da einen denkfehler drin.

viele Grüsse und vielen dank

Stephan



Damian

mit 

attr sleeptest startup setreading $SELF Fhem startet;;sleep 20;;set $SELF cmd_1

soll die Sequenz:

Zitatsetreading $SELF Fhem startet;;sleep 20;;set $SELF cmd_1

ausgeführt werden.

Das sieht mir aber nicht korrekt aus, denn setreading benutzt eine Readingangabe:

Zitatsetreading <device> <reading> <Inhalt>

Damit wird hier "Fhem" als Reading interpretiert.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

ich sehe gerade, dass das wohl beabsichtigt ist. Versuche es mal mit Komma:

attr sleeptest startup setreading $SELF Fhem startet,sleep 20;;set $SELF cmd_1

und im Attribut selbst darf nur ein Semikolon hinter sleep 20 stehen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Stelaku

Guten morgen Damian

Du bist wirklich schnell.

Du hast recht das ist nur ein Test Device in dem das mit den Reading beabsichtigt war. Leider blockiert Fhem bei einen rereadcfg auch dann wenn ich nur dieses im attr sleeptest startup  stehen habe.

sleep 20;set $SELF cmd_1
auch ein komma bringt keine Änderung.
sleep 20,set $SELF cmd_1

das zweite Semikolon kommt daher weil ich die Zeile aus der raw kopiert hatte.
aber wie gesagt Fhem blockiert nur bei einen rereadcfg.
Mache ich ein shutdown restart wird das attr startup normal abgearbeitet.

Viele Grüße

Stephan

MadMax-FHEM

#9
Aus vielen verschiedenen Gründen sollte (darf) man rereadcfg nicht mehr nehmen.

Gibt einiges dazu im Forum.
EDIT: z.B. https://forum.fhem.de/index.php/topic,127394.msg1219285.html#msg1219285

Also besser bei shutdown restart bleiben (wenn man schon so Sachen machen will/"muss")...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Stelaku

Hallo Joachim
Das ist auf jeden fall schon mal eine Gute info dann weiss ich bescheid und werde dann lieber immer auf einen shutdown restart zurückgreifen.

viele Grüße

Stephan

Damian

Zitat von: Stelaku am 06 November 2022, 10:57:15
Hallo Joachim
Das ist auf jeden fall schon mal eine Gute info dann weiss ich bescheid und werde dann lieber immer auf einen shutdown restart zurückgreifen.

viele Grüße

Stephan

Es muss auf jeden Fall etwas mit den allgemeinen FHEM-Mechanismen zu tun haben, denn selbst:

attr sleeptest startup {fhem"sleep 20;set bla on"}

blockiert.


Und da bin ich mir ziemlich sicher, dass DOIF diese Befehlsabfolge an FHEM weiterreicht.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF