CEC Remote Plugin

CEC Plugin

Plugin zum empfangen und senden von Kommandos via CEC.

Requirements

Installation:

Die angeschlossenen Geräte ermittelt man entweder mittels cec-client falls das Plugin noch nicht läuft:

echo "scan" | cec-client -s -d 1

Die Ausgabe sollte folgendermaßen aussehen:

    opening a connection to the CEC adapter...
    requesting CEC bus information ...
    CEC bus information
    ===================
    device #0: TV
    address:       0.0.0.0
    active source: no
    vendor:        Panasonic
    osd string:    TV
    CEC version:   1.4
    power status:  on
    language:      ger

   device #4: Playback 1
    address:       1.0.0.0
    active source: no
    vendor:        Panasonic
    osd string:    CECTester
    CEC version:   1.4
    power status:  on
    language:      eng

    device #8: Playback 2
    address:       2.0.0.0
    active source: no
    vendor:        Samsung
    osd string:    BD Player
    CEC version:   1.4
    power status:  on
    language:      ???

Auf einem VDR mit aktiviertem CEC-Plugin kann man die Information mittels svdrpsend abrufen:

svdrpsend plug cecremote LSTD

Die Ausgabe sollte folgendermaßen aussehen:

220 vdr SVDRP VideoDiskRecorder 2.0.7; Sun Mar  1 15:19:31 2015; UTF-8
214-Available CEC Devices:
214-  Device 0 path: /sys/devices/pci0000:00/0000:00:14.0/usb1/1-3 port: /dev/ttyACM0 Firmware 0004
214-
214-Active Devices:
214-   0# TV             @0000 TV              TV             Panasonic
214-   3# Tuner 1        @1000 Tuner 1         VDR            VDR
214-   4# Playback 1     @1000 VDR             VDR            VDR
214    8# Playback 2     @2000 BD Player       BD Player      Samsung
221 vdr closing connection

Im Konfigurationsverzeichnis des Plugins legt man die Datei cecremote.xml mit einem oder mehreren Einträgen für jedes Gerät ab, welches vom Plugin verwaltet werden soll. Eine Beispielkonfiguration findet sich im contrib-Verzeichnis im Plugin-Sourcecode.

Format der Konfigurationsdatei.

Die Datei ist eine XML Datei. Das Root-Element ist <config>. Innerhalb dieses Elementes gibt es ein <global> child Element zum Konfigurieren der globalen Optionen für dieses Plugin, sowie mehrere <menu>, <device>, <ceckeymap> und<vdrkeymap> child Elemente.

<ceckeymap>

Dieses Element enthält Definitionen um einen CEC Key einem oder mehreren VDR Keys zuzuweisen. Das <ceckeymap> Tag muss das Attribut "id" spezifizieren. Diese id wird später im <player> Abschnitt zum Auswählen der Keymap verwendet.

Dieses Element legt eine neue Keymap mit vorkonfigurierten Werten an. Elemente der Map können mit <key> überschrieben werden.

<vdrkeymap>

Dieses Element enthält Definitionen um einen VDR Key einen oder mehreren CEC keys zuzuweisen. Das <vdrkeymap> Tag muss das Attribut "id" spezifizieren. Diese id wird später im <player> Abschnitt zum Auswählen der Keymap verwendet.

Dieses Element legt eine neue Keymap mit vorkonfigurierten Werten an. Elemente der Map können mit <key> überschrieben werden.

<key>

Das Element wird innerhalb von <ceckeymap> oder <vdrkeymap> verwendet um existierende Map-Einträge zu überschreiben. Der <key> Tag muss das Attribut code angeben. code gibt den Key an, der neu definiert werden soll.

Wenn das Element in <ceckeymap> verwendet wird, so ist code ein CEC key name (siehe svdrpsend plug cecremote LSTK für eine Liste mit unterstützen CEC Key-Code Namen.

Wenn das Element in <vdrkeymap> verwendet wird, so ist code ein VDR-Key Name wie er z.B. in der keymacros.conf verwendet wird.

Das <key> Element beinhaltet <value> Elemente welches die Key-Codes beinhaltet. Falls kein <value> Element angegeben wurde, wird der Key-Code nicht verwendet. Es können beliebig viele <value> Elemente angegeben werden.

<value>

Dieses Element wird innerhalb <key> verwendet um Key-Codes zur Key-Map hinzuzufügen.

Wenn das Element <value> innerhalb von <vdrkeymap> verwendet wird so enthält <value> einen CEC Key-Name (siehe svdrpsend plug cecremote LSTK für eine Liste der unterstützten Namen).

Wenn das Element innerhalb von <ceckeymap> verwendet wird, so enthält <value> einen VDR-Key Name wie er z.B. in der keymacros.conf verwendet wird. Das folgende Beispiel legt eine neue Key-Map mit der id "TV" an, wobei der VDR key OK dem CEC "ROOT_MENU" key zugeordnet wird:

  <vdrkeymap id="TV">
    <key code="OK">
      <value>ROOT_MENU</value>
    </key>
  </vdrkeymap>

Das nächste Beispiel legt eine andere Key-map mit der id "TV" an. Wird der CEC Key-Code "SELECT" empfangen, so wird das in den VDR MENU Key übersetzt. Der Key-Code "RIGHT_UP" wird hier nach nur "right" übersetzt und nicht wie in der Default Key-Map nach right+up.

  <ceckeymap id="TV">
    <key code="SELECT">
      <value>Menu</value>
    </key>
    <key code="RIGHT_UP">
      <value>Right</value>
    </key>
  </ceckeymap>

<device>

Das <device> Element beinhaltet die Definition für CEC Devices. Der Haupteinsatzgrund ist, ein CEC Device per "physical address" zu spezifizieren, z.B. wenn es mehr als ein Recording-Device gibt. Die Zuweisung zur logischen Adresse kann hier unter Umständen von der Einschaltreihenfolge abhängen.

Das folgende Beispiel legt eine Konfiguration für einen BlueRay Player an, der am zweiten HDMI-Port des Fernsehers angeschlossen ist:

<device id="blueray">
   <physical>2000</physical>
   <logical>8</logical>
</device>

Die Software versucht zuerst die logische Adresse des Geräts mit der physikalischen Adresse 2000 zu ermitteln (zweiter HDMI-Port am TV, eine Beschreibung über HDMI siehe http://elinux.org/CEC_%28Consumer_Electronics_Control%29_over_HDMI).

Falls es mehrere Devices an der physikalischen Adresse gibt oder dort kein Gerät gefunden werden kann, wird als Fallback die spezifizierte logische Adresse (in dem Falle Playback 2) verwendet.

<global>

Die Elements innerhalb von <global> sind <cecdebug>, <rtcdetect>, <onstart>, <onmanualstart>, <onstop> <onswitchtotv>, <onswitchtoradio>, <onswitchtoreplay> <shutdownonstandby>, <poweroffonstandby> und <keymaps>.

<cecdebug> Debug level für CEC debugging (see cec_log_level in cectypes.h)
<onstart> Eine Kommando-Liste die beim Plugin-Start ausgeführt wird.
<onmanualstart> Eine Kommando-Liste die nur beim manuellen Plugin-Start ausgeführt wird und nicht bei einem Start durch einen Timer.
<onstop> Eine Kommando-Liste die beim Plugin-Stop ausgeführt wird.
<onswitchtotv> Eine Kommando-Liste die ausgeführt wird, wenn auf ein TV-Programm gewechselt wird.
<onswitchtoradio> Eine Kommando-Liste die ausgeführt wird, wenn auf ein Radio-Programm gewechselt wird.
<onswitchtoreplay> Eine Kommando-Liste die ausgeführt wird, wenn der VDR eine Aufnahme wiedergibt.
<keymaps> Der <keymaps> Tag hat das Attribut cec, welches die Id spezifiziert, die innerhalb <ceckeymap> angegeben wurde. Diese Keymap wird verwendet, um einen CEC-Keycode in einen VDR-Key zu wandeln.
<cecdevicetype> Die Device-Typen die mit libCEC für den VDR registriert werden. Die folgenden Typen sind verfügbar:
  • RECORDING_DEVICE
  • TUNER
  • TV
  • PLAYBACK_DEVICE
  • AUDIO_SYSTEM
ACHTUNG: Es gibt einen Bug in der libCEC Implementierung für den Raspberry PI der einen Absturz verursacht, wenn mehrere Typen registriert werden.
<hdmiport> Setzt den HDMI-Port an dem der CEC-Adapter angeschlossen ist.
<shutdownonstandby> Schaltet den PC in Standby wenn der Fernseher ausgeschaltet wird, allerdings nur wenn PowerOffOnStandby = false.
<poweroffonstandby> Schaltet den PC aus wenn der Fernseher ausgeschaltet wird.
<rtcdetect> Wenn dieses Element auf true gesetzt ist (Default) wird der RTC-Treiber benutzt um zu erkennen ob der VDR manuell oder über die RTC gestartet wurde. Wird dieses Element auf false gesetzt, oder es gibt auf der Maschine keine RTC, dann wird innerhalb eines Zeitraums von 5 Minuten vor oder nach einem Timer-Startzeitpunkt ein automatischer Start angenommen.
<startupdelay> Wartet eine Anzahl von Sekunden bis der CEC Adapter initialisiert und die <onstart> oder <onmanualstart> Kommando-Listen ausgeführt werden.

Die Kommando-Listen werden weiter unten beschrieben.

<menu>

Definiert einen Menü-Eintrag um CEC und Shell Kommandos auszuführen.

Der <menu> Tag muss folgende Attribute spezifizieren:

Die Elemente innerhalb von <menu> sind <onstart>, <onstop>, <player>, <onpoweron>, <onpoweroff>. <onstart>, <onstop> und <onpoweron>, <onpoweroff> schließen sich gegenseitig aus.

<player> : (siehe unten).
<onstart> : Eine Kommando-Liste die beim Auswählen des Menü-Eintrags ausgeführt wird.
<onstop> : Die Kommando-Liste wird ausgeführt wenn <stillpic> vorhanden ist und der Player gestoppt wird.
<onpoweron> : Die Kommando-Liste wird ausgeführt wenn das CEC-Device im Standby oder ausgeschaltet ist.
<onpoweroff> : Die Kommando-Liste wird ausgeführt wenn das CEC-Device derzeit eingeschaltet ist.

<player>

Startet einen Standbild-Player und wartet bis der Player beendet wird. Dieser Tag kann nicht zusammen mit <onpoweron> und <onpoweroff> verwendet werden.

Der <player> Tag muss folgendes Attribut spezifizieren:

Die Elemente innerhalb von <player> sind <stop> <onkey> <volumeup> <volumedown> und <keymaps>

<stop> : Kann mehrmals verwendet werden und beinhaltet einen VDR-Key um diesen Player zu stoppen.
<keymaps> : Der <keymaps> Tag hat die Attribute cec und vdr die die Id spezifiziere, die innerhalb <ceckeymap> oder <vdrkeymap> angegeben wurde. Wird der Player gestartet, so wird diese Keymap aktiv. Wird ein Tag nicht angegeben so wird die entsprechende "Default"" Key-Map verwendet.
<onkey> : Der <onkey> Tag benötigt das code Attribute.

<onkey code="VDR KEY"> wird verwendet um eine Kommando-Liste für einen VDR-Key für diesen Player zu definieren. Es können mehrere <onkey> Tags verwendet werden.

Das folgende Beispiel führt das Script volume_up.sh aus wenn der rote Knopf gedrückt wird.

  <onkey code="RED">
     <exec>volume_up.sh</exec>
  </onkey>
<volumeup> : Der <volumeup> Tag kann dazu verwendet werden eine Kommando-Liste für die Lautstärke + Taste zu definieren. Die Lautstärke wird aber weiterhin auch an das Ausgabe device geschickt.
<volumedown> : Der <volumedown> Tag kann dazu verwendet werden eine Kommando-Liste für die Lautstärke - Taste zu definieren. Die Lautstärke wird aber weiterhin auch an das Ausgabe device geschickt.

Kommando-Liste

Eine Kommando-Liste definiert eine Liste von Aktionen die ausgeführt werden.

Die Elemente innerhalb einer Kommando-Liste sind <poweron>, <poweroff>, <makeactive> und <exec>.

CEC Device Address kann entweder eine logische Adresse oder die Id eines <device> Tags sein.

<poweron>CEC Device Address</poweron> : Schaltet das Gerät ein.
<poweroff>CEC Device Address</poweroff> : Schaltet das Gerät aus.
<makeactive/> : VDR wird das aktive Gerät.
<makeinactive/> : Entfernt den VDR als aktives Gerät.
<textviewon>CEC Device Address</textviewon> : Sendet das TextViewOn CEC-Kommando.
<exec>Command</exec> : Führt ein Shell-Kommando aus.

SVDRP Kommandos.

LSTK : Listet alle unterstützten CEC Keycodes.
LSTD : Listet aktive CEC Devices.
KEYM : Listet alle Key-Maps
VDRK [id] : Zeigt die VDR->CEC Key-Map mit [id] an
CECK [id] : Zeigt die CEC->VDR Key-Map mit [id] an
CONN : Stellt eine Verbindung zu den CEC Adapter her.
DISC : Trennt die Verbindung zum CEC Adapter. Kann z.B. verwendet werden, wenn ein anderes Programm Zugriff auf den Adapter bekommen soll.

Commandline arguments

-c --configdir <dir> : Verzeichnis für die Konfigurationsdatei. Wenn der Verzeichnisname nicht mit einem / anfängt, ist das Verzeichnis relativ zum Konfigurationsverzeichnis vom VDR. Vorgabe ist cecremote.
-x --configfile <file> : Name der Konfigurationsdatei. Default ist cecremote.xml.

Probleme

Nach dem ersten Starten des VDR sollte man prüfen, ob der Modem Manager oder mtp-probe auf das Device zugreifen, indem man das Syslog nach dem Device-Path (/sys/devices/pci00 ...) durchsucht.

Im Syslog erkennt man solche Zugriffe mittels

    root@vdr:~> journalctl | grep /sys/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3
    Apr 30 16:57:37 vdr mtp-probe[746]: checking bus 1, device 4: "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3"
    Apr 30 16:57:52 vdr vdr[1105]: [cecremote] Device 0 path: /sys/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3 port: /dev/ttyACM0 Firmware 0001
    Apr 30 16:57:55 vdr ModemManager[538]: Couldn't create modem for device at '/sys/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3': Failed to find primary AT port

Dadurch kommt es zu einer längeren Startdauer und ggf. auch zu Instabilitäten

Eine udev rule die man z.B. unter /etc/udev/rules.d/20-libcec.rules installiert, unterbindet den Zugriff:

    # ModemManager and mtp probe should ignore /dev/ttyACM0
    ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="2548", ATTRS{idProduct}=="1002", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{MTP_NO_PROBE}="1"

Download