FHEM Modul für CEC-Kommandos

Begonnen von TheRelativ, 16 April 2020, 10:46:28

Vorheriges Thema - Nächstes Thema

TheRelativ

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? =)
FHEM @ Raspberry Pi3
868MhZ USB CUL @ Homematic (Thermostate + Heizungssteuerung)
433MhZ USB CUL @ Intertechno + 16-Channel FB zur Steuerung von FHEM Devices
2,4 GhZ nRF24L01+ PA-LAN for mySensors Network (~15 Dev.)
CC2530 USB Zigbee+Zigbee2MQTT (~30 Dev.)

Otto123

#1
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 schon mal skizziert.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

justme1968

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.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Otto123

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. :-*
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TheRelativ

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)
FHEM @ Raspberry Pi3
868MhZ USB CUL @ Homematic (Thermostate + Heizungssteuerung)
433MhZ USB CUL @ Intertechno + 16-Channel FB zur Steuerung von FHEM Devices
2,4 GhZ nRF24L01+ PA-LAN for mySensors Network (~15 Dev.)
CC2530 USB Zigbee+Zigbee2MQTT (~30 Dev.)

Beta-User

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.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TheRelativ

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.
FHEM @ Raspberry Pi3
868MhZ USB CUL @ Homematic (Thermostate + Heizungssteuerung)
433MhZ USB CUL @ Intertechno + 16-Channel FB zur Steuerung von FHEM Devices
2,4 GhZ nRF24L01+ PA-LAN for mySensors Network (~15 Dev.)
CC2530 USB Zigbee+Zigbee2MQTT (~30 Dev.)

Otto123

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 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 :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

TheRelativ

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
FHEM @ Raspberry Pi3
868MhZ USB CUL @ Homematic (Thermostate + Heizungssteuerung)
433MhZ USB CUL @ Intertechno + 16-Channel FB zur Steuerung von FHEM Devices
2,4 GhZ nRF24L01+ PA-LAN for mySensors Network (~15 Dev.)
CC2530 USB Zigbee+Zigbee2MQTT (~30 Dev.)

Otto123

#9
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 :)
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Beta-User

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).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

TheRelativ

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 =)
FHEM @ Raspberry Pi3
868MhZ USB CUL @ Homematic (Thermostate + Heizungssteuerung)
433MhZ USB CUL @ Intertechno + 16-Channel FB zur Steuerung von FHEM Devices
2,4 GhZ nRF24L01+ PA-LAN for mySensors Network (~15 Dev.)
CC2530 USB Zigbee+Zigbee2MQTT (~30 Dev.)

87insane

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.