Menüstruktur des vdr in einem Plugin abfragen (Ergebnis: das Plugin dbus2vdr - vdr zusätzlich per dbus steuern)

  • Moin!


    Für ein Experiment würde ich gerne das Menü des vdr in einem Plugin abfragen können - und zwar ohne, dass das OSD das Menü anzeigt. Über die cStatus-Schnittstelle (wie z.B. svdrposd es macht) möchte ich also nicht gehen.


    Die Menüpunkte des Hauptmenüs lassen sich schon mal so abfragen:

    Code
    cMenuMain *mainmenu = new cMenuMain;
    cString msg;
    for (cOsdItem *o = mainmenu->First(); o; o = mainmenu->Next(o))
        msg = cString::sprintf("%s%s\n", (*msg ? *msg : ""), o->Text());
    return msg;


    Aber wie nun weiter?
    Wie kriege ich die Untermenüs?
    Wie kriege ich die Einträge eines Untermenüs?
    Wie kann ich einen Menüpunkt auslösen?


    Ich werde mich noch weiter durch die Klassen aus menu.h, osdbase.h, osd.h usw. wühlen, aber wenn sich da schon jemand auskennt, wäre ich für einen Tipp dankbar...


    Lars.

  • Das dürfte wohl kaum möglich sein, da das Menü dynamisch nach Bedarf aufgebaut wird, und nicht statisch vorhersehbar ist. Man müsste schon mehr oder weniger simuliert durch alle Menüs 'durchlaufen', und hat dabei jederzeit das Risiko, dabei unbeabsichtigt irgend welche Aktionen anzustoßen: Ob ein Eintrag zum Aufruf eines Untermenüs führt, oder eine Aktion auslöst, ist nur vom Programmcode abhängig.


    Mal ganz davon abgesehen, dass wohl kein Menü dafür entwickelt wurde, ohne Anzeige auf dem OSD o.ä. aufgebaut zu werden, man muss also mit unerwarteten Fehlern in VDR und Plugins rechnen.


    Gruß,


    Udo

  • Moin!


    Das hab ich mir schon gedacht. Das Auslösen von Menüaktionen sehe ich noch nicht so ganz als Problem (das wird dann eher "Absicht").


    Was ich vor habe: Ein dbus2vdr-Plugin.
    Warum: Weil ich dbus kennenlernen will und ein kleines Bastelprojekt brauche - und momentan bin ich sowieso im vdr am wühlen und kennenlernen.
    Und ich denke, dass es auch etwas "schneller" als das eingebaute SVDRP läuft und eventuell auch schon benutztbar ist, wenn der vdr noch am Starten (oder noch gar nicht gestartet) ist, weil dbus wohl in der Lage sein könnte, ein paar Aufrufe zwischenzuspeichern (aber da bin ich noch am Lernen).


    Ich dachte da an Folgendes (für die, die ein wenig Ahnung von den dbus-Begriffen haben):
    Auf dem Session-Bus ein paar Interfaces bekanntgeben wie z.B.

    Code
    vdr.plugins.SVDRPCommand(Pluginname, Befehl)
    vdr.plugins.Service(Befehl, Parameter)
    vdr.menu.Select()
    vdr.SVDRPCommand(Befehl)


    Als Objektpfad würde ich dann sowas wie

    Code
    /Plugins/<Pluginame>/
    /Menu/...


    nehmen.
    Und für den "Menu"-Pfad müsste ich eigentlich nur wissen, ob es einen bestimmten Menüpunkt in einer Ebene gibt oder nicht - also ein komplettes Aufzählen ist eigentlich gar nicht nötig.


    So 100% hab ich da aber noch nicht drüber nachgedacht, ich bin da noch ganz am Anfang und am Voraussetzungen prüfen...
    Wenn ich das richtig gesehen habe, kann ich z.B. auch noch nicht intern (ohne Socket) einfach einen SVDRP-Befehl absetzen, wenn es kein Plugin betrifft. Die Plugins haben ja eine öffentliche Methode dafür.


    Vielen Dank erst mal, ich werde einfach ein wenig weiter "spielen". :)


    Lars.

  • Naja, ich weiß nicht. Ich persönlich halte nicht allzuviel von Dbus. Ist zwar mittlerweile im *Desktop*-Bereich mehr oder weniger Standard, aber ich sehe VDR auch nicht als Desktop-Applikation sondern als Daemon.


    Wesentlich sinnvoller wäre, wenn sich mal jemand mit dem Beschleunigen von SVDRP an sich befassen würde. Ist nämlich ziemlich langsam das Zeug...


    Beispiel: Ich habe ein Addon geschrieben, das eine Channels.conf aus dem Netz lädt und meine im VDR enthaltene Channels.conf nach der aus dem Netz geladenen synchronisiert. Also praktisch "Channel scan light". Änderungen werden so ohne "echten" Scan nachgeführt und auch neue Kanäle werden angelegt.


    Das Script selber läuft rasend schnell. Sobald ich es aber an SVDRP hänge, dass es tatsächlich etwas tut, dauert es minutenlang bis die nötigen Channel-Aktionen (DELC, MODC, NEWC) alle gelaufen sind. Dabei rasselt am laufenden Band die Festplatte. Vermutlich löst jeder einzelne Befehl einen Rewrite der channels.conf aus, was zu dieser enormen Laufzeit führt. Besser wäre es, die channels.conf erst auf Platte zu schreiben, wenn der Client wieder vom SVDRP trennt (QUIT oder disconnect).


    Soll nur ein Beispiel sein. Vermutlich sind auch die anderen Befehle nicht unbedingt auf Geschwindigkeit optimiert. Klassisches Beispiel: vdradmin, der beim ersten Connect eine gefühlte Ewigkeit braucht. Grund ist der "LSTE"-Befehl mit dem das EPG geholt wird. Um zu reproduzieren wie langsam der wirklich ist, einfach folgendes ausführen:


    svdrpsend.pl LSTE


    Ergebnis: Einige Zeit läuft das EPG über den Schirm, bis das in svdrpsend.pl hart eingebaute Timeout zuschlägt ;)

  • Moin!


    Der Auslöser für die dbus-Entwicklung ist sicherlich im Desktopbereich zu sehen, ist aber mittlerweile davon vollkommen unabhängig. Über den System-Bus können auch Daemons miteinander kommunizieren. Letztendlich ist es eine Alternative zu Sockets in der Inter-Process-Kommunikation.
    Und es ist auf niedrige Latenz ausgelegt.


    Aber ist auch egal, mir geht es nicht darum, ob das sinnvoll ist oder nicht. Ich möchte dbus kennenlernen und mir eine Meingung bilden, damit ich dann sagen kann, es taugt was oder eben nicht. :)
    Und momentan bin ich beim Hobbyprogrammieren sowieso nur im vdr unterwegs, deshalb kenne ich mich da gerade aus und hab auch ein Problem, das ich vermutlich mit dbus lösen kann.


    Mich stört nämlich nicht nur die langsame Verarbeitung der SVDRP-Befehle, sondern auch, dass ich die erst dann abschicken kann, wenn der vdr endlich so weit ist, die Befehle empfangen zu können. Und ich brauche es hauptsächlich für die Steuerung von ein paar Plugins.
    Und für dieses Problem werde ich sowieso ein kleines Plugin bauen, danach lässt sich sicherlich besser bewerten, ob es was taugt oder nicht.


    Ansonsten bin ich deiner Meinung (was die sonstige SVDRP-Geschwindigkeit betrifft). Vielleicht ist es auch an der Zeit, etwas Moderneres aufzubauen als "telnet". Wenn es die Zeit zulässt, werde ich da mal drüber nachdenken.


    Lars.

  • Zitat

    Originally posted by mini73
    Und ich brauche es hauptsächlich für die Steuerung von ein paar Plugins.


    Wäre es da nicht sinnvoller dann in diesen Plugins die Änderungen einzubauen als die irgendwie über eine Menüemulation fernzusteuern?


    Als Beispiel, ich wollte beim PIN Plugin die Kindersicherrung per Shell aktivieren/devaktivieren. Also Lösung gabs einige wenige Modifikationen des Quellcodes und jetzt geht "/usr/bin/fskcheck protect|unprotect". so ganz ohne Overhead, jederzeit und ohne Fehlermöglichkeiten. Egal wo im Menü sich das Plugin nun gerade einklingt oder wie es sich gerade nennt.


    cu

  • Ich vertrau mini73 da einfach mal ein stückweit. Was Desktopkommunikation angeht: Auf dbus geht:


    uDisks
    uPower
    upstart
    avahi


    usw. Einfach mal d-feet installieren und nachschauen. Ist wirklich interessant.


    Ich sehe nicht warum das für vdr nicht interessant sein sollte. Was die vdr internen Methoden angeht, denke ich ist dort wohl auch Potential - deine Performanceprobleme hängen dann aber weniger am SVDRP als an den Methoden selbst.

    VDR User: 87 - LaScala LC14B - LG/Phillipps 6,4" VGA Display | Asrock H61/U3S3 | G630T | 1x 16GB Mobi Mtron 3035 1x WD 750GB 2,5" |1x L4m DVB-S2 Version 5.4

  • Moin!


    Zitat

    Original von Keine_Ahnung


    Wäre es da nicht sinnvoller dann in diesen Plugins die Änderungen einzubauen als die irgendwie über eine Menüemulation fernzusteuern?


    Ja, ist es ja auch als Plugin-SVDRP-Kommando bzw. Service-Aufruf. Für mein spezielles Problem brauche ich das Menü nicht. Ich war bloß am Überlegen, was noch ganz "schick" wäre.


    Um mein "Problem" mal zu skizzieren:

    Code
    dbus-send --dest='vdr' /Plugins/dynamite vdr.plugins.SVDRPCommand string:'ATTD' string:'/dev/dvb/adapter0/frontend0'


    Sowas könnte schon abgesetzt werden, obwohl der vdr noch gar nicht in der Lage ist, SVDRP-Kommandos zu empfangen, weil er noch gar nicht richtig gestartet ist. Da gehen so einige Sekunden ins Land...
    Das dbus-Plugin könnte aber schon, sobald es geladen ist (das passiert ziemlich früh nach dem vdr-Start), auf dbus-Anfragen reagieren und diese sammeln, bis der vdr dann so weit ist, dass er die Befehle abarbeiten kann.


    Und wofür ich das Menü haben wollte:

    Code
    dbus-send --dest='vdr' /Menu vdr.menu.List
    dbus-send --dest='vdr' /Menu/4 vdr.menu.List


    würde dann die Hauptmenüpunkte bzw. die Menüpunkte des 4. Menüs auflisten


    Code
    dbus-send --dest='vdr' /Menu/4/7 vdr.menu.Select


    würde dann den siebten Menüpunkt im 4. Untermenü auslösen.
    Sozusagen ein Kommandozeilen-"OSD".


    Ist ja aber auch erst mal egal - lasst mich mal meine dbus-vdr-Plugin-Steuerung bauen, damit wir eine Grundlage zum Diskutieren haben. Vielleicht kommen dann die Anwendungsmöglichkeiten von ganz alleine. :)


    Vielleicht sowas?

    Code
    dbus-send --dest='vdr' /Recordings vdr.recordings.New ...
    dbus-send --dest='vdr' /EPG vdr.epg.New ...


    Da man bei dbus die einzelnen Parameter leichter angeben kann, könnte das lesbarer sein. Oder habt ihr schon mal probiert, über SVDRP einen Timer anzulegen...?


    Vielen Dank für die ganzen Kommentare! Ich freue mich auf die Resonanz, wenn es was "zum Spielen" gibt.


    Lars.

  • Moin!


    Das dynamite-Plugin reagiert schon auf udev-Ereignisse, das geht genauso gut.
    Ich will hier auch gar nicht über Pro und Kontra DBus diskutieren, denn ich werde das Plugin sowieso bauen. Weil ich dbus ausprobieren möchte! :)


    Aber wir weichen ab, hier hab ich ja nach Abfragemöglichkeiten des Menüs gefragt und das geht eben noch nicht...
    Gib mir zwei Wochen, bis ich genug Zeit finde, einen Rohbau zu erstellen, dann gibt's einen neuen Thread zum Thema DBus.


    Die vdr-DBus-Schnittstelle werde ich sowieso nur als Plugin bereitstellen, es wird also keine Abhängigkeit vom vdr zu DBus geben und jeder, der es möchte, kann sie dann einsetzen oder eben auch nicht.


    Lars.

  • Zitat

    Originally posted by mini73
    Das hab ich mir schon gedacht. Das Auslösen von Menüaktionen sehe ich noch nicht so ganz als Problem (das wird dann eher "Absicht").


    Um sich 'durchzuhangeln' musst du ja quasi jeden Menüeintrag mit einem generierten 'Ok' aufrufen. Was aber beim Eintrag 'Einstellungen' im Hauptmenü noch ein Untermenü generiert, löst beim Eintrag 'Restart' im Einstellungen-Menü nicht ganz das aus, was man will...


    Gruß,


    Udo

  • Moin!


    Jep. Das mit dem Menü hab ich auch erst mal ad acta gelegt - vielleicht gibt's ja irgendwann mal eine Möglichkeit, an einem Menüpunkt zu erkennen, ob's "nur" ein Untermenü ist. Oder überhaupt die Struktur abzufragen.
    Ich hab auch noch ein paar andere Baustellen, um die ich mich kümmern möchte...


    Vielen Dank für alle Beiträge!


    Lars.

  • Zitat

    Originally posted by Mreimer
    Sendet Device-Kit nicht ohnehin eine ganze Reihe von Deviceabhängigen Nachrichten über Dbus? Nehme doch die um dynamisch Devices einzuhängen. Dann braucht der VDR selber keine allgemeine Dbus-Schnittstelle.


    Das autostart Plugin macht ohnehin udisks.


    mini73: https://github.com/kersten/vdr-plugin-dbus kennst du aber oder ?


    Denkbar wäre svdrp auf dbus in geeigneter Weise oder andere Sachen die im VDR verfügbar sind aber nicht von aussen zugreifbar sind (da fällt mir grad nix zu ein) zur Verfügung zu stellen. Es wäre aber auch denkbar Infos auf dbus rauszuschieben (https://github.com/kersten/vdr…us/blob/master/Status.cpp) Es wäre sicher auch denkbar das Plugins interessante Sachen hierüber announcen. Oder das anhand bestimmter Filter oder wie auch immer gestaltet, Signale an upstart geschickt werden (ja ich weiss ich hab wieder die ubuntu/yavdr Brille auf). notify hat auch ein dbus interface.

    VDR User: 87 - LaScala LC14B - LG/Phillipps 6,4" VGA Display | Asrock H61/U3S3 | G630T | 1x 16GB Mobi Mtron 3035 1x WD 750GB 2,5" |1x L4m DVB-S2 Version 5.4

  • Moin!


    Zitat

    Original von steffen_b
    mini73: https://github.com/kersten/vdr-plugin-dbus kennst du aber oder?


    Klar, aber ich denke, die Aufgaben kann man gut trennen. Ich wollte ein Plugin, das Methoden zum Aufruf über dbus bereitstellt (erst mal als Alternative zu SVDRP).
    Ich wollte eigentlich nicht auf Signale von anderen reagieren oder andere dbus-Methoden aufrufen.
    Wenn man "dbus-input" und "dbus-output" voneinander trennt, hat man mehr Kontrolle über das, was man seinem vdr antun möchte.


    Lars.

  • Moin!


    Ich hab mal meine Gedanken in ein wenig Code umgesetzt:
    https://github.com/flensrocker/vdr-plugin-dbus2vdr


    Was es kann: SVDRP-Befehle an Plugins durchreichen (siehe README)


    Was noch fehlt: "Snickers-Feature" (Thread-Pool zum gleichzeitigen Abarbeiten mehrerer Aufrufe, insbesondere, wenn es "mal wieder länger" dauert)


    Geplant (weil's einfach ist): Service-Methode der Plugins aufrufen können


    Geplant (was etwas mehr Recherche benötigt): Umsetzung des PUTE-Befehls


    Feedback ist willkommen, ist aber alles noch nicht mal "alpha". :)


    Was mir schon mal gut gefällt, ist die niedrige Latenz zwischen Aufruf und Ausführung...


    Lars.

  • um mal den bekanntheitsgrad des plugins zu erhöhen:
    https://github.com/flensrocker…us2vdr/blob/master/README


    - send SVDRP commands to plugins
    vdr-dbus-send.sh /Plugins/femon plugin.SVDRPCommand string:'open

    Code
    method return sender=:1.38 -> dest=:1.39 reply_serial=2
       int32 900
       string "Opening femon plugin"


    und das femon menu taucht auf. string'quit' schliesst es wieder.


    - hit a key
    vdr-dbus-send.sh /Remote remote.HitKey string:'Menu'

    Code
    method return sender=:1.38 -> dest=:1.42 reply_serial=2
       int32 250
       string "Key "Menu" accepted"


    bling menu da ...


    - enable/disable the remote
    vdr-dbus-send.sh /Remote remote.Disable

    Code
    method return sender=:1.38 -> dest=:1.44 reply_serial=2
       int32 250
       string "Remote control disabled"


    gut für z.b. den switch nach xbmc


    vdr-dbus-send.sh /Remote remote.Enable

    Code
    method return sender=:1.38 -> dest=:1.45 reply_serial=2
       int32 250
       string "Remote control enabled"


    - get infos about the next timer
    vdr-dbus-send.sh /Timers timer.Next

    Code
    method return sender=:1.38 -> dest=:1.46 reply_serial=2
       int32 250
       int32 1
       int32 6477
       uint64 1303385880
       uint64 1303389900
       string "Lonely Planet - Ab vom Schuss"




    nicht getestet habe ich :


    - call Service method of plugins
    vdr-dbus-send.sh /Plugins/<pluginname> plugin.Service string:'id' string:'data'


    wie auch :D


    - read EPG data from file
    vdr-dbus-send.sh /EPG epg.PutFile string:'/path/to/epg/data'

  • Hier und da sicher praktisch, aber im Vergleich zu SVDRP noch "etwas schwach". Wenn man sicher weiß, dass der VDR läuft, ist man mit SVDRP letztlich besser dran.


    Ist es jetzt eigentlich so, dass diese dbus-Nachrichten gecachet werden? War ja ursprünglich mit ein Grund für das Plugin.

  • Moin!


    Kann ich dir noch nicht genau sagen, da meine (VDR-)Freizeit momentan arg beschnitten ist. Aber dbus2vdr ist beim Start auf alle Fälle schneller verfügbar als der SVDRP-Socket.
    Es soll auch kein Ersatz, sondern eine Ergänzung sein. Es ist insbesondere interessant, wenn man mit Python programmiert, da es da ein gutes dbus-Binding gibt und die Aufrufe an den vdr viel schöner sind.
    Ich muss mich aber noch etwas intensiver in dbus einarbeiten, um herauszufinden, ob man sogar vor dem Start des vdr schon Nachrichten abschicken kann.


    Und dbus2vdr ist multi-tasking-fähig - jeder Request wird in einem eigenen Thread abgearbeitet. Wenn mehrere Messages an dbus2vdr geschickt werden, werden sie auch alle abgearbeitet, da sie in einer Queue landen (im dbus-Daemon). Mein "Abholer" macht letztlich nichts anderes, als eine Nachricht zu holen, gucken, ob sie für dbus2vdr ist und einen Thread starten, damit das Ding abgearbeitet wird. Und es wird ein Threadpool benutzt, so dass ich nicht ständig neue Objekte instanziieren muss.


    Und geplant ist, es nach und nach um die Dinge zu erweitern, die benötigt werden (deshalb die bisherige Auwahl an Befehlen, weil die sich jemand gewünscht hat).


    Die SVDRP-Befehle des vdr lassen sich leider nicht von Plugins aus benutzen, da die einzelnen Methoden der Kommandos zu sehr mit dem Socket verbunden sind. Deshalb muss jeder SVDRP-Befehl nachprogrammiert werden.
    Bei den Plugins ist es etwas anderes, da jedes Plugin eine Methode "SVDRPCommand" hat, die den Befehl und Parameter entgegen nimmt und einen String zurückgibt, der dann an den Aufrufer gesendet werden muss. Deshalb lassen sich alle SVDRP-Befehle aller Plugins einfach so nutzen.


    Lars.

  • Ich glaube ich bin begeistert :) Ich nutze die lircrc und rufe damit dann auch svdrp Befehle (die dann letztendlich Plugins starten, z.B. die epgsearch Kanalanzeige) per Fernbedienungstasten auf, und mit der dbus Variante fühlt sich das flüssiger an als die svdrp Variante mit netcat. Werde mich dann später nochmal genauer damit beschäftigen, aber da ich bei mir auch viel per Python und svdrp EPG mache scheint das mit dem dbus auch ne gute Idee zu sein.


    Eine kleine Bitte hätte ich noch, könntest du auch das starten von Plugin mit aufnehmen?
    Ich nutze bei mir dazu folgenden Code


    Und es wäre shcön wenn das beim dbus Plugin mit drin wäre, weil im Moment ist DAS ein extra Plugin bei mir.


    cu

  • Moin!


    Das mach ich gerne, heute abend könnte ich dafür Zeit haben (bin momentan in Renovierungsstress).


    Genau so hab ich mir das vorgestellt, dass das Plugin so langsam um die wirklich benötigten Dinge erweitert wird. ;)


    Danke!


    Lars.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!