FHEM Forum

FHEM => Automatisierung => Thema gestartet von: JoeALLb am 07 März 2014, 09:37:43

Titel: Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: JoeALLb am 07 März 2014, 09:37:43
Wenn ich ein setreading in einem userReading versuche
fhem("setreading Kalender_google nextStime 20:00")

erhalte ich folgende Fehlermeldung, und FHEM reagiert nicht mehr.

Deep recursion on subroutine "main::readingsEndUpdate" at fhem.pl line 3575.
Deep recursion on subroutine "main::fhem" at (eval 25723) line 1.
Deep recursion on subroutine "main::AnalyzeCommandChain" at fhem.pl line 2715.
Deep recursion on subroutine "main::AnalyzeCommand" at fhem.pl line 776.
Deep recursion on subroutine "main::fhem" at (eval 25723) line 1.
Deep recursion on subroutine "main::AnalyzeCommandChain" at fhem.pl line 2715.
Deep recursion on subroutine "main::AnalyzeCommand" at fhem.pl line 776.
Deep recursion on subroutine "main::CommandSetReading" at fhem.pl line 892.
Deep recursion on subroutine "main::readingsSingleUpdate" at fhem.pl line 1731.



Nun kann ich mir vorstellen, dass es nicht gewünscht ist, diese Kombination auszuführen?!?
Ich hatte im Userreadeing jedoch zwei Werte ermittelt , die je für ein userReading gedacht sind.
Um Ressourcen zu schonen wollte ich den zweiten Parameter direkt in ein zweiter userReading schreiben, anstatt ihn in einem eigenen userReading über die selbe Berechnung nochmals zu ermitteln und zu setzen.

Leider war ich unterwegs und hatte keinen SSH-Zugriff für den Neustart, weshalb meine Warmwassersteuerung für heut vormittag ausgefallen ist ;-)
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: betateilchen am 07 März 2014, 10:26:20
mit Setreading kannst Du ein echtes Reading schreiben, selbst eines, das es im Device gar nicht gibt.

setreading('deviceBla','gustav',10)

würde problemlos funktionieren.

Bei den userReadings, die für einen anderen Zweck gedacht sind (nämlich um in Abhängigkeit selbstständig den Wert zu verändern) wird die Funktion intern genutzt. Du versuchst also gerade, ein Reading mit setreading() zu verändern, das gerade selbst dabei ist, sich zu ändern. Und das geht nicht.

Du solltest Dich also entscheiden, ob Du ein userReading definierst, das sich selbst (abhängig) aktualisiert,
oder ob Du einfach Deine beiden Readings mit setreading manuell beschreiben willst, dann dürfen die aber nicht als userReading definiert sein.
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: JoeALLb am 07 März 2014, 10:40:48
Danke für die Info!
Ich bin schon dabei, eine Andere Lösung dafür zu erarbeiten.

Zitat von: betateilchen am 07 März 2014, 10:26:20
Bei den userReadings, die für einen anderen Zweck gedacht sind (nämlich um in Abhängigkeit selbstständig den Wert zu verändern) wird die Funktion intern genutzt. Du versuchst also gerade, ein Reading mit setreading() zu verändern, das gerade selbst dabei ist, sich zu ändern. Und das geht nicht.

ich wollte aber ein ANDERES Reading(einzweites) damit verändern! Nicht das userReading, in dem sich der Code befindet. Von daher verstehe ich die Recursion nicht ganz....
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: betateilchen am 07 März 2014, 10:56:44
naja, wie gesagt: Innerhalb des userReadings läuft schon ein setreading.

Leider sind hier im Thread zu wenige Fakten über das, was Du eigentlich erreichen willst und darüber, wie Du das alles zusammengeschräubelt hast. Vielleicht könnte man Dir sonst eine völlig simple Lösung vorschlagen.
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: JoeALLb am 07 März 2014, 11:48:00
Ich wollte es einfach selber schaffen, und dachte, dieser Weg könnte gehen;-)

Ich versuche, Einen Wecker auf der Musikanlage (Sonos) nach einem Google-Wecker zu stellen.
Der Aufruf für Sonos ist lt. http://www.fhemwiki.de/wiki/Sonos_Anwendungsbeispiel folgender.

set Sonos_Wohnzimmer Alarm Create 0 { Enabled => 1, Volume => 35, StartTime => '00:00:00', Duration => '00:15:00', Repeat => 0, Shuffle => 0, ProgramURI => 'x-rincon-buzzer:0', ProgramMetaData => ' ', Recurrence_Once => 0, Recurrence_Monday => 1, Recurrence_Tuesday => 1, Recurrence_Wednesday => 1, Recurrence_Thursday => 1, Recurrence_Friday => 1, Recurrence_Saturday => 0, Recurrence_Sunday => 0, IncludeLinkedZones => 0 }:


Dazu möchte ich die Werte des _nächsten_ Kalendereintrag aus Googel übernehmen.

Um an die Werte des Kalenders zu kommen habe ich dort mal (um es zu prüfen)
dieses Userreading eingefügt
nextSDate:modeUpcoming { CalendarParse($name);}
((Genau hier wollte ich zur Anzeige gleich alle 4 Rückgabewerte in eigene Readings schreiben, und nicht 4 eigene userReadings definieren.))

das folgenden Perlcode aufruft.
sub
CalendarParse($)
{
my ($name) = shift;
if (not $name){
return '';
}

my ($uid)=ReadingsVal($name,'modeUpcoming',0)=~ /([^;]+)/;
my $erinnerungsname= fhem("get Kalender_Wackers full $uid");
my ($sdate,$stime,$edate,$etime) = $erinnerungsname =~ /.*?([\d\.]+)\s([\d:]+)-([\d\.]+)\s([\d:]+).*/;

return ($sdate,$stime,$edate,$etime)
}



Damit erhalte ich Anfags und Enddatum sowie die Uhrzeit.
Was noch fehlt ist:
* die Umrechnung in hh:mm der Dauer des Weckers, also von Endzeit des Weckers minuns Anfangszeit
* verhindern, dass der Wecker bei jedem Abrufen des Kalenders geschrieben wird (also nur bei Veränderungen)
* aktivieren eines Kalenders, der nicht am nächsten, sondern erst am übernächsten Tag aktiviert werden soll. dies hat jedoch keine priorität.

Daraus möchte ich dann folgende notify generieren,
um den (bereits definierten Wecker 43) zu aktualisieren.

Kalender_x:modeUpcoming.*googlecom {
my ($sdate,$stime,$edate,$etime) = CalendarParse($name);
set Sonos_Schlafzimmer Alarm Update 43 { Enabled => 1, Volume => 10 , StartTime => '$stime', Duration => '????'};
}



Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: betateilchen am 07 März 2014, 12:19:32
mit der Hand durch die Brust ins Auge...

Warum definierst Du nicht einfach ein notify, das direkt mit dem Kalender zusammenarbeitet?
Im Kalendereintrag steht doch sowieso die Start- und Endzeit des "Events" und Du brauchst gar nix mehr auszurechnen.

mit calendarStarted triggerst Du das Einschalten, mit calendarEnded triggerst Du das Ausschalten. Das sind beides events, die vom Kalender ausgelöst werden und die Du völlig einfach in notify verwenden kannst. So steuere ich z.B. meine Raumheizungen (ich gebe im Kalender die Temperatur zu Beginn des Events und die Temperatur, die am Ende eingestellt werden soll an) indem ich einen Kalendereintrag mit dem Betreff: "wz_Heizung 20.5 16.0" und dem Zeitraum 18-22 Uhr anlege. Dann wird automatisch um 18 Uhr die Heizung im Wohnzimmer auf 20.5 Grad und um 22 Uhr auf 16 eingestellt.

Ähnlich mache ich es mit Schaltaktoren, da ist es noch einfacher. Im Betreff steht z.B. sz_Bett_rechts und der Termin geht von 20:00 bis 05:00. Damit wird die Wasserbettheizung des rechten Bettes im Schlafzimmer um 20 Uhr ein- und um 05 Uhr ausgeschaltet. Das ist im Prinzip die gleiche Anwendung wie für Deinen Wecker.

Nutze einfach die Möglichkeiten, die der Calendar Dir out-of-the-box schon liefert, das macht doch viel mehr Spaß!
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: JoeALLb am 07 März 2014, 12:46:28
Zitat von: betateilchen am 07 März 2014, 12:19:32
mit calendarStarted triggerst Du das Einschalten, mit calendarEnded triggerst Du das Ausschalten.
Ich möchte auch geweckt werden, wenn der Kalender nicht ins Internet kommt, da die Fritzbox noch aus ist.

Zitat von: betateilchen am 07 März 2014, 12:19:32
Das sind beides events, die vom Kalender ausgelöst werden und die Du völlig einfach in notify verwenden kannst.
Damit kann ich aber nur direkt das Play starten, nicht den Alarm setzen. Sonst müsste ich ja einen Alarm setzen, der "jetzt sofort" losgeht.
Ich möchte aber unbedinmgt den Alarm starten, da dieser folgende Vorteile hat:
* er fängt "leise" an und wird mit der zeit lauter
* Er hat ein "Ablauftimer", das ich jederzeit am Sonos-Controller sehe und verlängern kann (eine art umgekehrte snooze-funktion)

Wenn ich nur auf das calendarEnded einen Stopbefehl schicke (was ich im moment übrigens mache und was auch funktioniert!),
sehe ich im Sonos-system nicht, wie lange der Radio noch an bleibt und wann er ausgehen soll.

Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: betateilchen am 07 März 2014, 13:13:07
Du hast mich immer noch nicht verstanden. Ok, ich gebe auf.
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: JoeALLb am 07 März 2014, 13:20:56
Zitat von: betateilchen am 07 März 2014, 13:13:07
Du hast mich immer noch nicht verstanden. Ok, ich gebe auf.
Ist ja ok, dass Du aufgibst, danke dennoch für den Versuch mir zu helfen, aber warum soll ich mich mit einer Lösung zufrieden geben, die mir nichts hilft?

im Übrigen ging es hier ja nicht um mein Kalender-Problem, sondern um den Fehler der Rekursion.

Ich weiß nicht, ob sowas vorab abgefangen werden sollte, jedoch kann ich damit FHEM zum absturz bringen.
Titel: Antw:Aufruf von Setreading in userReading nicht möglich: -> 'Deep recursion'
Beitrag von: betateilchen am 07 März 2014, 13:23:41
Zitat von: JoeALLb am 07 März 2014, 13:20:56jedoch kann ich damit FHEM zum absturz bringen.

Dafür gibt es tausende Möglichkeiten, die man nie wird abfangen können.