Apple Airport, Sonos und HomeKit - Überbrückung bis zum Airplay 2 Support

Begonnen von DokHasenbein, 09 Dezember 2017, 19:48:08

Vorheriges Thema - Nächstes Thema

DokHasenbein

Ich habe noch eine alte Airport-Express an einem Sonos angeschlossen. Wie wahrscheinlich weitgehend bekannt, kann man damit Apple-Airplay-Streaming am angeschlossenen oder auch jedem anderen Sonos-Speaker durchführen (dies ist die offizielle Lösung, die auch in den Sonor-Anleitungen beschrieben wird). Sonos hat inzwischen Support für Airplay 2 angekündigt, der aber möglicherweise noch länger auf sich warten lassen wird und soweit ich weiß auch nicht sicher mit alten Sonos-LS funktionieren wird. Ich wollte nun etwas mehr Komfort und habe dazu einige FHEM-Notifies und einen Dummy-Schalter konstruiert, den ich nun hier mit der Allgemeinheit teilen möchte. Vielleicht findet es ja jemand nützlich.

Die Verwendung ist recht einfach:
1.) Der folgende Code muss nach 99_myUtils.pm kopiert werden.
2.) Jetzt kann in der FHEM-Kommandozeile mit  {CreateAirplayDevice4Sonos("BELIEBIGESSONOS","SONOSAIRPLAYDEVICE")} das Paket aus FHEM-Notifies und dem Dummy-Device erzeugt werden. BELIEBIGESSONOS kann jeder Sonos sein (auch das SONOSAIRPLAY Bei Bedarf für jeden Lautsprecher auf dem Airplay-Wiedergegeben werden kann wiederholen.
3.) Über das Dummy-Device kann nun das Airplay-Signal auf jedem Lautsprecher an- und abgestellt werden.
4.) Das Dummy-Device wird in den Raum "Homekit" gelegt und kann so nach einem Neustart von Homebridge auch über Siri gesteuert werden.

Dies ist mein erstes veröffentlichtes FHEM-Projekt. Bitte Feedback geben, wenn es Probleme geben sollte oder auch gerne wenn es funktioniert und nützlich gefunden wird.

Viel Spaß damit

DokHasenbein


sub
CreateAirplayDevice4Sonos($$)
{
unless (scalar(@_) == 2) {
Log(1,"Usage: CreateAirplayDevice4Sonos(\"RemoteSonosPlayer\", \"AirplaySonosplayer\")");
exit 1;
}
my ($sonosname,$sonosairplayname) = @_;
unless (defined($defs{$sonosname})) {
Log(1,"$sonosname is undefined. Please define it first.");
exit 1;
}
unless (defined($defs{$sonosairplayname})) {
Log(1,"$sonosname is undefined. Please define it first.");
exit 1;
}
if (sonosIsInGroup($sonosairplayname)) {
  Log(1,"$sonosairplayname is in a group. Please set $sonosairplayname MakeStandaloneGroup first, then try again.");
  exit 1;
}
my $airplaydummyname = $sonosname."_Airplay";
    my $switchOnNotify = $sonosname."_On_Notify";
    my $switchOffNotify = $sonosname."_Off_Notify";
    my $sourceNotify = $sonosname."_Source_Notify";
    my $airplayURI = "x-rincon-stream:".ReadingsVal($sonosairplayname,"ZonePlayerUUIDsInGroup","");
my $aliasname = AttrVal($sonosname,"alias","");
    unless (defined($defs{$airplaydummyname})) {
    fhem("define $airplaydummyname dummy");
        fhem("attr $airplaydummyname devStateIcon on.*:audio_audio off.*:audio_volume_mute");
        fhem("attr $airplaydummyname room Homekit");
        fhem("attr $airplaydummyname setList on off");
unless ($aliasname eq "") {fhem("attr $airplaydummyname alias Airplay-$aliasname");}
fhem("attr $airplaydummyname event-on-change-reading .*");
        fhem("setreading $airplaydummyname airplayURI ".ReadingsVal($sonosairplayname,"ZonePlayerUUIDsInGroup",""));
    }
    unless (defined($defs{$switchOnNotify})) {
        fhem("define $switchOnNotify notify $airplaydummyname:on.* {if (ReadingsVal(\"$sonosname\",\"currentTrackURI\",\"\") ne \"$airplayURI\") {\
my \$currTrack = ReadingsVal(\"$sonosname\",\"currentTrackURI\",\"\");;\
fhem(\"setreading $airplaydummyname prevTrackURI \$currTrack\");;\
fhem(\"set $sonosname playURI $sonosairplayname\");;}\
  else {fhem(\"set $sonosname Play\")}}");
    }
    unless (defined($defs{$switchOffNotify})) {
        fhem("define $switchOffNotify notify $airplaydummyname:off.* {if (ReadingsVal(\"$sonosname\",\"currentTrackURI\",\"\") eq \"$airplayURI\") {\
        # Irgendwie vorherigen Track wiederherstellen, aber wie?\
fhem(\"set $sonosname Stop\");;\
}}");
    }
    unless (defined($defs{$sourceNotify})) {
        fhem("define $sourceNotify notify $sonosname:currentTrackURI:.* {\
  if (\$EVENT =~ \"$airplayURI\") {fhem(\"set $airplaydummyname on\");;} else {fhem(\"set $airplaydummyname off\");;}}");
}
}