Jump to content
NeuDLi

Abändern von Timern durch Eventghost / Abfangen des Ruhezustands

Recommended Posts

NeuDLi

Hallo zusammen,

 

falls dieses Thema hier nicht hinpasst, bitte entsprechend verschieben. Alles andere schien mir aber noch unpassender.

 

Folgende Ausgangssituation:

 

Ich benutze den Recording Service für meine Aufnahmen, und mache sehr viel Gebrauch von EPG-Suchen mit automatischer Programmierung (anders ist das bei den unzuverlässigen Zeiten gerade bei den Privaten für Serien nicht mehr zu handhaben). Normalzustand nach Aufnahme ist Ruhezustand. Das funktioniert alles sehr sehr zuverlässig, nicht gestartete Aufnahmen wegen Nicht-Aufwachens kommen nicht mehr vor (außer durch eigene Dummheit...). Aus einer Paranoia heraus habe ich jedoch einen Raspberry per Ethernet mit dem HTPC verbunden, der per WOL morgens um 6.00 die Kiste aufweckt, falls sie doch mal nicht aus dem Ruhezustand kommen sollte.

 

Weiterhin benutze ich Eventghost als Fernbedienungslösung.

 

Da bekanntermaßen ein Windows 7 nach langer Laufzeit ohne Neustart manchmal zickig wird, und automatische Windows-Updates auch meist nur mit Neustart installiert werden, möchte ich gerne die Kiste ab und an nicht in den Ruhezustand schicken, sondern runterfahren. Da wie oben erwähnt ohnehin um 6.00 ein Neustart erfolgt, auch in runtergefahrenem Zustand, mache ich das bisher so, dass ich den letzten Timer, der davor endet, manuell auf Runterfahren statt Ruhezustand nach Aufnahme einstelle.

 

Das würde ich gerne automatisieren. Da Eventghost ja ohnehin läuft und wirklich sehr mächtig ist, müsste sich das doch irgendwie regeln lassen.

 

Die Luxus-Version wäre es, abzufragen, ob ein Timer vor 6 Uhr beendet wird, und dessen Aktion beim Beenden auf Runterfahren zu ändern ("aktive" Variante). Ob das möglich ist, weiß ich aber nicht. Zumindest das Abfragen müsste gehen.

 

Alternativ und vermutlich einfacher: bei jedem Mal, wo nach einer Aufnahme der Ruhezustand ausgelöst wird, mit EG abfragen, ob bis 6.00 noch eine weitere Aufnahme ansteht, und falls nicht, stattdessen Runterfahren. Das sollte sich doch machen lassen.

 

Ich hab schon viel gesucht und über EG und dessen DVBV-Plugin gelesen, aber so richtig weiter hilft mir das alles bisher nicht. Also wenn mich jemand in die richtige Richtung weisen könnte, wo man sich dazu Anregungen holen könnte, wäre ich sehr dankbar.

 

Oder gibt es vielleicht alternative Lösungsansätze, die ich nicht sehe? Etwa über die Windows-Aufgabenplanung?

Share this post


Link to post
mague

Was fuer ein OS hat dein Rassberry ?

 

Du kannst mit

http://[user:password@]IP[:port]/api/timerlist.html[?utf8=]

die timer abrufen. Da steht die Endzeit drin. Wenn diese vor 06:00 Uhr ist und die nächste Aufnahme nach 06:00 Uhr ist, dann kannst du den timer mit

http://[user:password@]IP[:port]/api/timeredit.html

bearbeiten und die endact auf power off stellen.

 

Wenn auf dem RasPi ein Linux laeuft kann man das leicht mit curl in einem bash script machen. Das Script wird dann von einem cronjob regelmässig aufgerufen.

Edited by mague

Share this post


Link to post
NeuDLi

Wenn auf dem RasPi ein Linux laeuft kann man das leicht mit curl in einem bash script machen. Das Script wird dann von einem cronjob regelmässig aufgerufen.

 

Na schon mal vielen Dank, auf die Idee wäre ich nämlich gar nicht gekommen! Und ist eigentlich auch besser, denn dadurch übernimmt der gleiche Beteiligte (RasPi) sowohl das Runterfahren als auch das erneute Anwerfen. Mit anderen Worten, liefe der RasPi nicht, könnte auch nix schiefgehen.

 

Auf dem RasPi läuft Raspbian, das ist also kein Thema. Cron kann ich bedienen. Von "leicht mit curl" kann aber keine Rede sein... mit Scripting und Parsen etc. bin ich noch nie so recht Freund geworden. Na ich werde mich mal einlesen und nochmal melden, falls es gar nicht klappen sollte.

 

So schon mal händisch probiert, einen Timer zu ändern, aber ich kriege es einfach nicht hin, von einem bestehenden Timer die endact=1 zu setzen! So sollte es doch gehen (wobei ich auch nicht weiß, ob die ID mit oder ohne geschweifte Klammer zu setzen ist, geht aber beides nicht) mit curl:

 

[...]/timeredit.html?id=1234&endact=1

 

Das tut aber nicht. Der Timer bleibt bestehen wie er vorher war, auch wenn der Befehl keinen Fehler ausgibt. Was mache ich da falsch? Ein paar ausgeschriebene Beispiele wären auf http://en.DVBViewer.tv/wiki/Recording_Service_API echt hilfreich für Anfänger wie mich...

Edited by NeuDLi

Share this post


Link to post
NeuDLi

So, ein bisschen weiter bin ich gekommen. Aus einem alten Thread ergab sich, dass die richtige ID nicht die eindeutige, kryptisch lange ist, sondern die kurze am Ende des Eintrags. Die ist allerdings nicht eindeutig, sondern nur zur Laufzeit des RS gleich.

 

Curl hat mich dann noch weiter geärgert, weil es das "&" nicht berücksichtigt. Auch hier hilft Google, man muss es in einfache Klammern setzen.

 

Gut, wie man an einem Timer die Endaktion ändert, weiß ich nun.

 

Jetzt muss ich "nur" noch hinbasteln, wie ich aus der Timerliste die richtigen Daten passend extrahiere, um den letzten Timer vor 6.00 herauszufischen. Erschwerend kommt da hinzu, dass mir die Sortierung der Timereinträge nicht verständlich ist. Wer mag mir mit grep, regexp und Co. ein bisschen auf die Sprünge helfen?

Share this post


Link to post
NeuDLi

Suspendghost hab ich zwar gesehen, aber ein Reboot ist ja eben nicht das, was ich will. Denn danach muss die Kiste ja wieder runterfahren, wenn sie nicht dauernd an sein soll. Und überhaupt hatte ich nach dem Durchlesen den Eindruck, dass Suspendghost viel zu viel Zeug macht, was ich so nicht will.

 

So, wie ich es vorhabe, ist der Vorteil, dass kein einziger Powercycle den Festplatten mehr zugemutet wird, als ohnehin gemacht würde.

 

Außerdem, nachdem ich jetzt mal auf die vermutlich richtige Idee gebracht wurde, lasse ich mich doch nicht von einem Programmier-Problem davon abhalten :-). Es wird ja wohl möglich sein, die timers.xml so zu parsen, dass man den Timer mit der letzten Endezeit vor 6.00 rauspickt (und prüft, ob keine weitere Aufnahme vor 6.00 beginnt). Ich brauche ja nur die zugehörige ID dazu herauszubekommen.

Share this post


Link to post
mague

Hi,

 

hier ein kleiner Anfang mit bash. Es gibt sehr gute Handbücher und Tutorials zu bash. Auch zu loops und Abfagen mit if oder case.

 

timer.zip

 

Edit: timers.tip aktualisiert.

Edited by mague

Share this post


Link to post
NeuDLi

Vielen Dank, das sieht nach genau dem richtigen Ansatz aus, den ich brauche. Ich hätte auch schon selbst angefangen, mich schlau zu machen, aber derzeit erlaubt es meine Zeit nicht (Frau UND Kind krank...).

 

Ich melde mich dann zurück, wenn alles soweit klappt, vielleicht ist das für jemand anders auch eine Hilfe für ähnliche Aufgaben. Wie man nicht nur hier sieht, ist so ein Raspberry Pi eine sehr nützliche Erweiterung für einen HTPC mit DVBViewer...

Share this post


Link to post
mague

Ich hab ein neues script hochgeladen. Das macht auch etwas looping und so :)

Share this post


Link to post
NeuDLi

Noch mehr, was ich vom Profi lernen kann :-), erneut herzlichen Dank. Es gibt allerdings ein Problem, auf das ich beim Selberbasteln auch schon gestoßen bin:

 

Das Dumme ist, dass in den Timern nicht immer die gleiche Anzahl Elemente vorhanden sind! Sofern die Ende-Aktion "Keine Aktion" ist, fehlt das Feld "Shutdown=?", bei Überwachen von PDC gibt es ein weiteres Feld "PDC="???"... Vermutlich gibt es auch noch andere optionale Felder, die ich nicht auf dem Schirm habe.

 

Und das kann ich nicht ändern bzw. will ich nicht. Manchmal braucht es eben einen Timer, der nachher nichts tut. Und PDC überwachen geht meines Wissens auch nur richtig mit den Öffentlichen.

 

Alles kein grundsätzliches Problem, ich muss nur mal wieder genug Zeit dafür haben und Deinen Code verstehen. Dann sollte es kein Thema sein, denn letztendlich sind ja nur die folgenden Felder relevant, die man rausfiltern muss:

- Datum, das muss bei allen relevanten Timern mit dem aktuellen übereinstimmen, alle von späteren Tagen sind zu verwerfen;

- Endezeit, die muss beim betreffenden Timer die letzte vor 6.00 sein;

- Anfangszeit, die muss bei dem nächsten Timer nach 6.00 liegen, sonst klappts an dem Tag nicht;

- <ID>??</ID>, das ist die ID, die man zum Ändern übergeben muss.

 

Bei meiner derzeitigen Timerliste sieht der Output von Deinem Skript so aus, wobei das Ergebnis für heute stimmt, aber es gibt die folgenden Fehler:

 

$ ./timers
Es gibt 4 timer

Timer <Timer endet Dur="59" - Alles gut
./timers: Zeile 48: [: 07.12.2014: Ganzzahliger Ausdruck erwartet.
Timer <Timer beginnt Date="07.12.2014". Bitte modifizieren !
(das ist ein Timer in der Zukunft)
endet PreEPG="5" - Alles gut
beginnt Dur="60". Alles gut

endet End="02:00:00" - Alles gut
beginnt Start="01:05:00". Alles gut
Timer EPGEventID="30901" endet End="00:55:00" - Alles gut
Timer EPGEventID="30901" beginnt Start="22:40:00". Bitte modifizieren !

 

Wie man sieht, klappt es trotz der Fehler korrekt. Das wird also, jetzt muss ich nur die Zeit und Muße haben, das zu verstehen und den letzten Rest an Arbeit zu machen. Wie gesagt: vielen Dank!

Share this post


Link to post
mague

Du kannst die Ausgabe von curl auch zeilenweise in ein Array schreiben. Dann ist der Inhalt egal und der 15er offset stört nicht mehr.

 

curl -silent 'http://user:pass@host.or.ip:port/api/timerlist.html' | grep "Timer Type" >timers.txt

I="0"

while read line

do

MYTIMERS[$I]=$line

I=$[$I+1]

done < timers.txt

 

 

Danach muß man halt die einzelnen Werte rauspulen. Geht alles. bash ist weniger Programmiersprache, eher sowas wie ein Legobaukasten. :)

Edited by mague

Share this post


Link to post
NeuDLi

So nach langer krankheits- und Feiertags-bedingter Untätigkeit melde ich mich wieder. Irgendwie war mir der bisherige Ansatz für das zu Erreichende schlicht viel zu komplex. Außerdem nervt es doch sehr, dass die nötigen IDs mehr oder weniger "ausgewürfelt" werden, je nach Art des Timers nicht alle Felder auftauchen und und und... Daher hab ich es vorläufig quick and dirty mit einem Shutdown-Timer gelöst, nachdem der Raspberry per WOL den HTPC wieder anwirft. Nicht schön, unzuverlässig (siehe unten) und es erzeugt natürlich zusätzliche Powercycles der Festplatten.

 

Aber heute bin ich auf eine andere Idee verfallen, die eigentlich näher dran ist an meinem ursprünglichen Plan. Es ist ja relativ einfach, das debuglog mittels curl auf dem Raspberry abzurufen (und da reichen ja die letzten paar Seiten). Darin wird nämlich nach Beenden eines Timers wunderschön genau das eingetragen, was ich eigentlich brauche: "09.01.15 15:41:09.483 TRecordingEngine Setting next recording: 09.01.2015 21:32:00". Und im Gegensatz zu den Timern ist das debuglog auch hierarchisch sortiert, d.h. der letzte Eintrag, der auf dieses Muster passt, ist immer die nächste Aufnahme.

 

Damit kann selbst ich mit meinen bescheidenen Bash-Fähigkeiten prüfen, ob die nächste Aufnahme so liegt, dass man zwischendurch einen Shutdown mit anschließendem Aufwecken durch den Raspberry ausführen kann. Und sollte das so sein, kann man relativ einfach erneut mittels curl einen Shutdown auslösen. Was ich noch testen muss: ob der Shutdown Vorrang vor dem Timer-gesteuerten Hibernate hat, aber ich schätze schon, und sonst gibts auch da Möglichkeiten.

 

Einziges kleines Manko: danach wird ja relativ schnell die Aktion ausgeführt, die für den Timer eingetragen ist, also bei mir Hibernate. Verzögert nur durch die Zeitspanne, die für die Shutdown-Warnung vorgegeben ist, damit ein Benutzer das noch abbrechen könnte. Innerhalb dieser Zeitspanne muss der Raspberry also sicher Auslesen, Prüfen und den Shutdown einleiten, sonst nützt es nichts. Sollte sich mit einem regelmäßigen curl-Abruf und einer entsprechend dimensionierten Zeitspanne für die Warnung machen lassen, zumal mitten in der Nacht niemand das WLAN nutzt, den das stören könnte, minütlich oder so 512 kb rumzuschubsen. Der Riesenvorteil dieser Lösung: sollte der Raspberry mal nicht laufen, wird auch nicht Heruntergefahren, was bisher ja ohne Zutun des Raspberry per Timer passiert. Sollte der aber nicht laufen, würde der HTPC zwar wie geplant Runterfahren aber nie wieder automatisch aufwachen und alle Aufnahmen verpassen, bis ich es merke... also keine zuverlässige Lösung.

 

Eleganter wäre es sicher, das Abrufen nur dann zu machen, wenn der Recording Service in das Log schreibt, allerdings habe ich keine Ahnung, wie man das lösen könnte... Möglicherweise, indem man den Log-Ordner auf Linux mountet und dann die Datei auf Änderungen prüft. Ob Samba dafür zeitlich präzise genug ist, weiß ich aber nicht. Zu dumm, dass man für das Log keinen separaten Speicherort vorgeben kann...

 

Soviel zu meinen Überlegungen und Versuchen von heute. An und für sich müsste alles so klappen. Ob das so funktioniert, werde ich morgen testen und dann weiter berichten.

Share this post


Link to post
NeuDLi

So, jetzt habe ich das mal zusammengeschrieben und getestet. Es scheint zu funktionieren... der finale Härtetest kommt dann heute nacht.

 

Nötig, damit es funktioniert, sind noch die folgenden Punkte, die nichts mit dem Skript zu tun haben:

 

- Cronjob, der das Skript zwischen 0:00 und 7:45 minütlich ausführt (Offset zum WOL aus Sicherheitsgründen, damit das Runterfahren bis dahin sicher erledigt ist);

- Cronjob, der den HTPC um 8:00 per WOL weckt;

- Wartezeit vor dem Beenden in Recording Service auf 120 Sekunden (weniger reicht sicher auch, aber das scheint mir ein vernünftiger Wert).

 

Das Skript sieht dann so aus:

 

#!/bin/bash
# Zeit, zu der HTPC per WOL geweckt wird
WT=8

# altes debuglog löschen
if [ -e /tmp/debuglog ]; then
rm /tmp/debuglog
fi

# letzte 512 kB vom debuglog abrufen

if [ -e /tmp/debuglog ]; then
# Datum der nächsten Aufnahme
NRD=$(grep "Setting next recording" /tmp/debuglog | tail -n 1 | cut -c69-78)
# Zeit der nächsten Aufnahme
NRT=$(grep "Setting next recording" /tmp/debuglog | tail -n 1 | cut -c80-81)
# aktuelles Datum
CD=$(/bin/date "+%d.%m.%Y")

if [ "$NRD" = "$CD" ]; then
# nächste Aufnahme am heutigen Tag
echo "nächste Aufnahme heute: $NRD"
if [ $NRT -ge $WT ]; then
# nächste Aufnahme nach WOL-Zeit
echo "nächste Aufnahme später als $WT Uhr: $NRT Uhr"
echo "Shutdown auslösen"
# Shutdownbefehl an Recording Service senden

else
echo "nächste Aufnahme früher als $WT Uhr: $NRT Uhr"
echo "Shutdown nicht auslösen"
fi
else
echo "nächste Aufnahme nicht heute: $NRD"
echo "Shutdown nicht auslösen"
fi
fi

Share this post


Link to post
NeuDLi

So, nun ist es geschafft... allerdings anders als geplant und erwartet. Die vorstehende Lösung (bei der, wie ich jetzt erst sehe, Zeilen fehlen, keine Ahnung warum) konnte leider nicht funktionieren, da der auslösende Begriff immer erst genau dann im debuglog erscheint, wenn unmittelbar danach die Shutdown-Aktion ausgelöst wird. Das Timeout wird nicht danach, sondern davor abgearbeitet. Konnte also nicht funktionieren.

 

Da ich nun aber schonmal so weit war, auf eine anstehende Shutdown-Aktion zu prüfen, was ja meine anfängliche Idee war, habe ich das einfach anders gelöst. Unmittelbar vor dem Beginn des eingestellten Timeouts erscheint im debuglog nämlich "EvaluateShutdown" als letzte Zeile. Das benutze ich jetzt als Auslöser, um zu prüfen, ob die nächste Aufnahme nach dem WOL-Zeitpunkt liegt, und falls ja, sende ich einen Shutdown-Befehl zum Runterfahren an den Recording Service.

 

Von meiner Seite aus ist das Problem damit nun endgültig gelöst. Wenn jemand noch an Erläuterungen Interesse hat, bitte einfach melden. Während der Bastelei habe ich inzwischen auch eine Möglichkeit gefunden, wie von mague vorgeschlagen einen bestimmten Timer abzuändern, z.B. den, der vor dem WOL-Zeitpunkt liegt. Für den (zwar unwahrscheinlichen, aber man weiß ja, wie das mit Murphy ist...) Fall, dass nämlich jemand nachträglich noch eine Aufnahme programmiert, die nach diesem auf Herunterfahren geänderten Timer aber vor dem WOL-Zeitpunkt starten soll, würde das aber zuverlässig diese Aufnahme verhindern, da der Rechner nicht aufwachen könnte. Insgesamt finde ich meine Lösung daher besser, da fehlertoleranter. Aber vielleicht kann das mal für was anderes nützlich sein.

 

Das finale Skript sieht folgendermaßen aus:

 

[EDIT: wenn mir jemand erläutern kann, wie ich eine Datei anhänge, mache ich das auch, aber bei mir kommt jedes Mal der Fehler "No file was selected for upload", wenn ich es versuche]

Edited by NeuDLi

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...