Hallo zusammen,
ich experimentiere seit einigen Tagen mit cec-utils und habe das auch fast soweit dass ich es anwenden.
Der Gedanke der mir kam, es wäre doch viel einfacher, wenn es ein Modul gäbe, welches den CEC-Traffic versteht und in FHEM Devices umsetzt.
Klar, cec ist vom Prinzip her einfach, man kann sich auch sämtliche Befehle mit http://www.cec-o-matic.com/ zusammenbauen bzw. auch decodieren lassen, aber dann muss für jedes Device ein notify usw eingerichtet werden.
Schöner wäre es, wenn man die Roh Traffic Ausgabe von cec-utils mittels einer named pipe an FHEM weitergeben könnte.
Mein Aufbau bisher:
- ein Raspberry Pi Zero W mit HDMI Kabel am Fernseher
- installierte cecutils und libcec-dev
Ein Script um das cec Tool als "Daemon" zu starten sowie ein-/Ausgabe in Named Pipes zu leiten:
if [ -f "/tmp/cecclient_i.pipe" ]; then
mkfifo /tmp/cecclient_i.pipe
fi
if [ -f "/tmp/cecclient_o.pipe" ]; then
mkfifo /tmp/cecclient_o.pipe
fi
SERVICE="cec-client"
if pgrep -x "$SERVICE" >/dev/null
then
echo "$SERVICE is running"
else
echo "starting $SERVICE"
killall tail
killall cec_reader.sh
(/usr/bin/tail -f /tmp/cecclient_i.pipe | /usr/bin/cec-client -d 8 &) > /tmp/cecclient_o.pipe &
fi
SERVICE="cec_reader.sh"
if pgrep -x "$SERVICE" >/dev/null
then
echo "$SERVICE is running"
else
echo "starting $SERVICE"
/home/pi/cec_reader.sh &
fi
Ein Script um die Ausgabe-Pipe auszulesen, aktuell zu Debug-Zwecken einfach nur in eine Log-umgeleitet, aber daraus kann man ja machen was man möchte:
#!/bin/bash
pipe=/tmp/cecclient_o.pipe
while true
do
if read line <$pipe; then
if [[ "$line" == 'quit' ]]; then
break
fi
echo $line >> /home/pi/cecreader.log
fi
done
echo "Reader exiting"
mit z.B. echo "tx 10:36" > /tmp/cecclient_i.pipe kann ich den TV in standby versetzen (Sender Logical ID:1 ist Raspberry, Empfäner ID:0 der TV, 36 der Code für Standby)
Mit dem oben angegebenen Log-Level (-d 8) erhält man im Log folgende Ausgaben:
TRAFFIC: [ 1435037] << 1f:84:10:00:01
TRAFFIC: [ 1474721] << 10:36
waiting for input
TRAFFIC: [ 1475601] >> 0f:36
TRAFFIC: [ 1540722] >> 0f:87:00:00:f0
TRAFFIC: [ 1540722] << 1f:87:00:15:82
TRAFFIC: [ 1541692] >> 2f:84:10:00:01
TRAFFIC: [ 1543458] >> 0f:87:00:00:f0
TRAFFIC: [ 1543459] << 1f:87:00:15:82
TRAFFIC: [ 1544428] >> 2f:84:10:00:01
TRAFFIC: [ 1546288] >> 5f:87:00:00:f0
TRAFFIC: [ 1548141] >> 0f:87:00:00:f0
TRAFFIC: [ 1548141] << 1f:87:00:15:82
TRAFFIC: [ 1549111] >> 2f:84:10:00:01
Ohne setzen des Log-Levels bekommt man auch Menschen-Lesbare ausdrücke, aber da denke ich sind diese "Maschinen-Lesbaren" Ausdrücke gerade für Module besser geeignet.
Die Idee also, aus dem Raspberry Pi Zero W eine FHEM Instanz mit einem neu zu schaffenden CEC-Moduls, welches den Stream aus der Ausgabe Pipe bekommt und selbst Befehle in die Eingabe Pipe senden kann. Das Modul erstellt Devices anhand der Physical Address, die Logical Address kann als Attribut/Reading zusätzlich auftauchen.
Bei einem beispielweise "set tv on" (wobei tv eines der neuen devices ist) sendet das neue Modul dann "tx 10:04" an die Eingabe Pipe (10 = Raspberry an TV, 04 = einschalten)
Mittels FHEM2FHEM kann man alle Devices und Readings vom Raspberry Pi Zero W an die Hauptinstanz weiterleiten.
Die Hauptinstanz kann die Befehle dann mit bspw. system("echo 'set tv on' | /usr/bin/socat - TCP:1.2.3.4:7072"); auf der anderen Instanz absetzen.
Die Große Frage, gibt es jemanden der so ein Modul entwickeln möchte? =)
Hi,
alternative Idee: Ein "MQTT Device" bauen?
Man könnte einfach mosquitto-clients installieren und dann in dem Daemon die Ausgabe Werte zur MQTT2 Instanz in FHEM publishen. Bzw. auch wieder einen Topic abonnieren und auf den geeignet reagieren.
Das Ganze lässt sich damit auf scriptlevel abhandeln erfordert kein lokales FHEM. Mit MQTT wird es universeller und man braucht kein spezielles Modul.
Die dafür notwendigen Grundgedanken hatte ich hier (https://heinz-otto.blogspot.com/2019/11/mqtt-ich-muss-das-testen.html)schon mal skizziert.
Gruß Otto
schau dir mal an wie das tradfri modul einen externen prozess startet und mit dessen stdio kommuniziert. der externe prozess kann auch per ssh auf einem entfernten rechner gestartet werden. die gleiche methode per Prozess bzw. inzwischen gekapselt in CoProcess.pm wird auch in anderen modulen verwendet.
den umweg über mqtt etwas neues in fhem einzubinden das nicht von sich aus schon mqtt spricht halte ich für nicht gut.
Naja der Prozess "cec am Fernseher" spricht erstmal nichts was FHEM versteht. Dort in etwas zu übersetzen, was FHEM sowieso schon versteht und auch über einen Standard Kommunikationsweg funktioniert, halte ich für besser als einen neuen Sprachkundigen in FHEM auszubilden.
Und wenn ich an die Arien denke wie leicht es die Benutzer finden ssh mit public key für user fhem einzurichten :'(
Ich finde nicht das es ein Umweg ist, aber war nur eine Idee - vielleicht war die doof. :-*
die MQTT Variante klingt ehrlich gesagt gar nicht mal so schlecht.
Man bräuchte dann auf dem HDMI-Raspberry nur ein MQTT Client und ein Script was daraus senden/empfängt und übersetzt.
Auf der anderen Seite könnte man die von mir gebauten Pipes nutzen.
Publishen geht laut deiner Seite mit mosquitto_pub, wie bekomme ich anders rum hin dass der hdmi-raspberry auf bestimmte topics lauscht?
also
CEC-Traffic -> Output Pipe -> Übersetzungs-Script -> mosquitto_pub -> MQTT Server -> FHEM
anders rum
FHEM -> MQTT Server -> ??? -> Übersetzungs-Script -> Input-Pipe -> CEC-Kommando
Man könnte jedes physical oder logical device (ich muss da nochmal genau nachdenken was besser wäre) als eigenes topic publishen und diverse Eigenschaften mitgeben die ebenfalls via CEC gesendet werden (Geräte-Typ, OSD-Name, HDMI-CEC-Version, letztes Kommando auf der FB)
Eventuell kann dieser Fund von Rince schnell weiterhelfen: https://forum.fhem.de/index.php/topic,70251.msg617774.html#msg617774
Trotzdem sollte man ggf. justme1968's Einwand erstmal auf sich wirken lassen.
Achso ich vergas noch zu erwähnen dass das ganze nicht nur mit Fernsehern funktioniert, ich kann mit Hilfe von CEC auch meine PS4 und den Bluray Player ein-/ausschalten.
Gerade die PS4 Steuerung habe ich nach stundenlangem googlen nichts gefunden, was die PS4 aus dem ausgeschatetem Zustand weckt, das klappte alles nur aus dem Ruhemodus mit Hilfe eines Virtuellen PS4 Gerätes.
Mittels CEC lässt sich die PS4 auch aus dem ausgeschaltetem Zustand wecken, selbst wenn sie vorher komplett Stromlos war.
p.s. damit der "standby" Befehl via CEC die PS4 auch wieder richtig ausschaltet, muss der Ruhemodus in der PS4 deaktiviert und damit auf Downloads in der Ruhephase verzichtet werden.
Zitat von: TheRelativ am 16 April 2020, 11:36:26
Publishen geht laut deiner Seite mit mosquitto_pub, wie bekomme ich anders rum hin dass der hdmi-raspberry auf bestimmte topics lauscht?
Da gab es weiter unten einen Link (https://unix.stackexchange.com/questions/188525/how-to-subscribe-a-bash-script-as-a-mqtt-client) zu einer Idee.
Müsste man Beides in Eines packen. Aus meiner Sicht wäre das ein Lösungsansatz/Baustein für verschiedene Dinge. Da könnte auch der Windows Multimedia PC am Fernseher stecken :)
Wenn meine Pipe Scripte laufen, funktioniert folgendes modifiziertes Script um MQTT Befehle von FHEM Richtung HDMIpi zu senden:
#!/bin/bash
##########################
# MQTT Shell Listen & Exec
host=xxx
mqttuser=xxx
mqttpass=xxx
ctrl_c() {
echo "Cleaning up..."
rm -f $p;kill $pid 2>/dev/null
if [[ "$?" -eq "0" ]];
then
echo "Exit success";exit 0
else
exit 1
fi
}
listen(){
p="backpipe";pid=$(cat pidfile)
([ ! -p "$p" ]) && mkfifo $p
(mosquitto_sub -h $host -u $mqttuser -P $mqttpass -i cec_global -t cmd/cec_global/raw >$p 2>/dev/null) &
echo "$!" > pidfile
while read line <$p
do
if $line == 'quit'; then
(rm -f $p;rm $clean;kill $pid) 2>/dev/null
break
else
echo $line > /tmp/cecclient_i.pipe
mosquitto_pub -h $host -u $mqttuser -P $mqttpass -i cec_global -t tele/cec_global/lastcmd -m done
fi
done
}
trap ctrl_c INT
listen
esac
An der Stelle noch das Problem, dass der mosquitto_sub nur auf 1 Topic lauscht, hier muss ich schauen ob er auf mehrere IDs/Topics parallel lauschen kann und man im Script irgendwie das angesprochene Gerät unterscheiden kann.
Außerdem bräuchte man noch eine einfache Methode und eigene "Sprache" um xx:36 in "standby" bzw. xx:04 in "on" für die MQTT Befehle zu übersetzen, am besten etwas universelles was in beiden Richtungen funktioniert um nicht 10 Millionen Bash Scripte am ende zu haben ;D
zur Idee von justme1968 da müsste dann nur jemand dran er Ahnung davon hat, ich müsste mich in die Modulerstellung erst komplett einlesen und reintesten
Ich denke das geht im MQTT2 Device mit setList?
So in der Art
Zum Schalten (Kopie aus tasmota Device):
off:noArg cmnd/tasmota_A52F4C/POWER1 0
on:noArg cmnd/tasmota_A52F4C/POWER1 1
Zum Darstellen/Übersetzen dann mit readingList :)
Zitat von: Otto123 am 16 April 2020, 12:55:09
Ich denke das geht im MQTT2 Device mit setList?
So in der Art (Kopie aus tasmota Device):
off:noArg cmnd/tasmota_A52F4C/POWER1 0
on:noArg cmnd/tasmota_A52F4C/POWER1 1
Betrifft nur die eine Richtung... Aber auch die andere sollte gehen, z.B. als Kombination aus https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/lib/AttrTemplate/mqtt2.template#L2686 und https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/lib/AttrTemplate/mqtt2.template#L3029.
Also: Perl in der readingList, darüber dann einen Hash abchecken und das Ergebnis nach state schreiben (am Ende muß ein Hash nach dem Muster {Reading=>Value} (bzw. mehrere Reading-Value-Paare) übergeben werden).
ZWars etwas verspätet aber hier eine Rückmeldung.
Ich habe die o.a. cec-mqtt-bridge nun im Einsatz, das ganze läuft nicht so gut unter python3.7 deswegen habe ich python mit version 3.4 komplett neu installiert und die cec-Module installiert die mit dem GIT-Paket mitkamen.
Funktioniert soweit, ich bekomme nun die CEC-Codes im Rohformat an FHEM sowie On/Off Stati der einzelnen logical IDs.
Mit einem notify und hex2decimal sowie hex2string funktionen konnte ich einiges auslesen und als Reading für Dummy Devices übernehmen.
Leider reagiert mein Fernseher nicht auf Push/Release CEC-Befehle. Die Befehle Volup/Voldown werden standardmäßig an ID 5 (Sound System) gesendet, das funktioniert nur wenn ich ein externes Sound System auch einschalte.
d.h. mein Fernseher reagiert nur auf On/Off =(
ABER: Was mich deutlich weiter bringt, ich kann via HDMI die PS4 ein und wieder ausschalten und somit auch PS4 Remote Play nutzen ohne dass die Playsi ständig im Standby hängen muss =)
Hole das Ding hier nochmal hoch. Vermutlich baue ich gerade genau sowas. Aktuell noch ein wenig gefudelt über ein mqtt fake device innerhalb von fhem.
Am liebsten wäre mir irgendwas HDMI/esp/mqtt mäßiges. Dazu überlege ich mir aktuell noch was. Es gibt diverse threads zu dem Thema aber auch diverse projekte im GIT.
Lange Rede kurzer Sinn. Am ende wird es ähnlich wie bei sonos2mqtt laufen. Deswegen würde ich mich über Unterstützung freuen.