Yamaha Musiccast Modul

Ich bin gerade dabei für meine Yamaha Netzwerkreceiver und Netzwerkplayer ein Modul zu erstellen.
Es gibt zwar bereits ein super Modul von traxanos, aber damit lassen sich die Musikfunktionen noch nicht steuern.

Da dies mein erstes Modul ist und meine Programmierkenntnisse noch etwas bescheiden sind, wird es vermutlich noch eine ganze Weile dauern bis ich alles in ein Modul packen kann.

Über jegliche Art von Verbesserungsvorschlägen und über jede Art von Mithilfe wäre ich sehr dankbar.

Aktuell habe ich das Ganze mit 2 Skripten und manuell angelegten Variablen gelöst und alles funktioniert soweit.
Getestet habe ich mit einem Yamaha WX-010 Netzwerkplayer.

Hier schon mal meine Skripte und Variablen. Vielleicht hilft das ja schon dem Einen oder Anderen weiter.

Gruß
Michl

Webfont

Variablen

Skript „Yamaha Netzplayer steuern.php“

<?

//Benötigte Skripte importieren
include (IPS_GetScriptFile (16175 /*[ZZZZ_Neu\Yamaha Netzplayer\Yamaha Netzplayer\Yamaha Netzplayer Funktionen]*/) );

############################################################

//Variablen initialisieren
$debug = false;
$test = 0;
$value = 0;
$ID = 0;

$Modul_ID = 28581 /*[ZZZZ_Neu\Yamaha Netzplayer\Yamaha Netzplayer]*/; //ID vom Dummy Modul anpassen !!!
$Skript_ID = IPS_GetScriptIDByName ("Yamaha Netzplayer steuern", $Modul_ID );
$ID_Power = IPS_GetVariableIDByName("Power", $Modul_ID);
$ID_Volume = IPS_GetVariableIDByName("Volume", $Modul_ID);
$ID_Mute = IPS_GetVariableIDByName("Mute", $Modul_ID);
$ID_Eingang = IPS_GetVariableIDByName("Eingang", $Modul_ID);
$ID_Playback = IPS_GetVariableIDByName("Playback", $Modul_ID);
$ID_NetPreset = IPS_GetVariableIDByName("Netradio Stationen", $Modul_ID);
$ID_EventSync = IPS_GetEventIDByName("Sync", $Skript_ID);


############################################################

if ($_IPS['SENDER'] == "Variable")
{
$value    = $_IPS['VALUE'];    	//Wert der Variable zum Auslösezeitpunkt
$ID = $_IPS['VARIABLE'];   //ID der auslösenden Variable
}

if ($_IPS['SENDER'] =='TimerEvent')
{
$ID = $_IPS['EVENT'];
}

############################################################
if ($debug == true) {
//DEBUG

	//$Ausloeser = IPS_VARIABLE;
	$Sendervalue    = $_IPS['VALUE'];
	$SenderTyp = $_IPS['SENDER'];
	$SenderID = $_IPS['EVENT'];
	$Variable = $_IPS['VARIABLE'];

	//IPS_LogMessage($_IPS['SELF'], "Ausloeser: ". $Ausloeser);
	IPS_LogMessage($_IPS['SELF'], "value: ". $Sendervalue);
	IPS_LogMessage($_IPS['SELF'], "SenderTyp: ". $SenderTyp);
	IPS_LogMessage($_IPS['SELF'], "SenderID Event: ". $SenderID);
	IPS_LogMessage($_IPS['SELF'], "SenderID Variable: ". $Variable);
	
	//Testvariablen (können an entsprechende Stellen kopiert werden
	setvalue (22576 /*[ZZZ_Test\Testvariable Bool]*/, $test);
	setvalue (43046 /*[ZZZ_Test\Testvariable Integer]*/, $test);
	setvalue (33902 /*[ZZZ_Test\Testvariable String]*/, $test);
	
	}
############################################################

//Power on und Standby
if ($ID == $ID_Power) {
	if ($value == true)	{
	setPower('on');
	}
	else {
	setPower('standby');
	}
}

//Lautstärke
# Muss noch getestet werden !!!
if ($ID == $ID_Volume) {
	SetVolume ($value);
	}


//Mute
if ($ID == $ID_Mute) {
	SetMute($value);
	}
 

//Eingang setzen
if ($ID == $ID_Eingang) {
	switch ($value) {
	case 0: //Auswahl Button
	break;
		
	case 1:
	setInput('net_radio');
	break;
	
	case 2:
	setInput('airplay');
	break;
	
	case 3:
	setInput('bluetooth');
	break;
	
	case 4:
	setInput('server');
	break;
	
	case 5:
	setInput('mc_link');
	break;
	
	default:
	die("Unbekannter Wert $value für Input");
	}
}

// Preset von Netradio umschalten
if ($ID == $ID_NetPreset) {
	if ($value > 0) CallPreset($value);
	IPS_Sleep(500);
	SetValue (14101 /*[ZZZZ_Neu\Yamaha Netzplayer\Yamaha Netzplayer\Netradio Stationen]*/, 0);
	}

//Playback steuern
if ($ID == $ID_Playback) {
	switch ($value) {
	case 0:
	setPlayback('previous');
	break;
		
	case 1:
	setPlayback('play');
	break;
	
	case 2:
	setPlayback('pause');
	break;
	
	case 3:
	setPlayback('stop');
	break;
	
	case 4:
	setPlayback('next');
	break;
	
	default:
	die("Unbekannter Wert $value für Playback");
	}
}



//Synchronisieren
if ($ID == $ID_EventSync) {
	SyncStatus();
	SyncNetPlayInfo();
	}


?>

Skript „Yamaha Netzplayer Funktionen.php“

<?

//Variablen initialisieren und herausfinden
//------------------------------------------------------- 
//Manuell anpassen
#$host = GetValue (32599 /*[ZZZZ_Neu\Yamaha Netzplayer\Yamaha Netzplayer\IP-Adresse]*/);
$host = '192.168.5.89';      //IP des Gerätes anpassen! Netzplayer im Gang
#$host = '192.168.5.66';      //IP des Gerätes anpassen! Yamaha Wohnzimmer

$Zone = 'main'; //Zone anpassen Values: "main" / "zone2" / "zone3" / "zone4"
#$Zone = 'zone3';

$Modul_ID = 28581 /*[ZZZZ_Neu\Yamaha Netzplayer\Yamaha Netzplayer]*/; //ID vom Dummy Modul anpassen !!!
//------------------------------------------------------- 

//Variablen IDs herausfinden
$Skript_ID = IPS_GetScriptIDByName ("Yamaha Netzplayer steuern", $Modul_ID );
$ID_Power = IPS_GetVariableIDByName("Power", $Modul_ID);
$ID_Volume = IPS_GetVariableIDByName("Volume", $Modul_ID);
$ID_Mute = IPS_GetVariableIDByName("Mute", $Modul_ID);
$ID_Eingang = IPS_GetVariableIDByName("Eingang", $Modul_ID);
$ID_Playback = IPS_GetVariableIDByName("Playback", $Modul_ID);
$ID_Interpret = IPS_GetVariableIDByName("Interpret", $Modul_ID);
$ID_Lied = IPS_GetVariableIDByName("Lied", $Modul_ID);
$ID_Album = IPS_GetVariableIDByName("Album", $Modul_ID);
$ID_Cover = IPS_GetVariableIDByName("Cover", $Modul_ID);
$ID_NetPreset = IPS_GetVariableIDByName("Netradio Stationen", $Modul_ID);
$ID_EventSync = IPS_GetEventIDByName("Sync", $Skript_ID);

##############################################################################################
//-----------------------------------------------
//Steuern

function setStandby(){
	global $Zone;
	$Data = "{$Zone}/setPower?power=standby";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}

function setPowerOn(){
	global $Zone;
	$Data = "{$Zone}/setPower?power=on";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}

function setPower($Power){		
	//Values: "on" / "standby" / "toggle"
	global $Zone;
	$Data = "{$Zone}/setPower?power={$Power}";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}
	
function SetVolume ($Volume){		
	global $Zone;
	#setVolume?volume=50
	$Data = "{$Zone}/setVolume?volume={$Volume}";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}
	
function SetMute($OnOff){
	global $Zone;
	if ($OnOff == 1) $Mute = 'true';
	else $Mute = 'false';
	$Data = "{$Zone}/setMute?enable={$Mute}";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}

function CallPreset($Preset){
#http://{host}/YamahaExtendedControl/v1/netusb/recallPreset?zone=main&num=13 //Preset 13 wird aufgerufen
	global $Zone;
	$Data = "netusb/recallPreset?zone={$Zone}&num={$Preset}";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}
	
function setInput($Input){
#http://{host}/YamahaExtendedControl/v1/main/setInput?input=airplay&mode=autoplay_disabled
# hier könnte noch autoplay an / aus integriert werden
	global $Zone;
	$Data = "{$Zone}/setInput?input={$Input}";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben
	}
	
function setPlayback($Playback){
	$Data = "netusb/setPlayback?playback={$Playback}";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //Antwort ausgeben

/* Values: "play" / "stop" / "pause" / "play_pause" / "previous" / "next" /
"fast_reverse_start" / "fast_reverse_end" / "fast_forward_start" /
"fast_forward_end"
*/
	}

##############################################################################################
//-----------------------------------------------
//Auslesen


function getDeviceInfo(){
	$Data = "system/getDeviceInfo";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //alle Infos ausgeben
}


function getFeatures(){
	$Data = "system/getFeatures";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //alle Infos ausgeben
}


function getStatus(){
	global $Zone;
	$Data = "{$Zone}/getStatus";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //alle Infos ausgeben
	return ($Answer);
}

function getNetPreset(){ //Speicherstationen vom Netplayer
	$Data = "netusb/getPresetInfo";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //alle Infos ausgeben
}

function getNetPlayInfo(){ //aktuelle Infos vom Netplayer auslesen
	$Data = "netusb/getPlayInfo";
	$Answer = SendCommand ($Data);
	print_r(json_decode($Answer)); //alle Infos ausgeben
	return ($Answer);
	}


##############################################################################################
//Synchronisieren
function SyncStatus(){

global $ID_Power;
global $ID_Volume;
global $ID_Mute;
global $ID_Eingang;
global $ID_Playback;
global $ID_Interpret;
global $ID_Lied;
global $ID_Album;
global $ID_Cover;
global $ID_NetPreset; 

	$Answer = getStatus();
	$object = json_decode($Answer);
	//Werte zuordnen
	$response = $object->{'response_code'};
	$Power = $object->{'power'};
	$Volume = $object->{'volume'};
	$Mute = $object->{'mute'};
	$MaxVolume = $object->{'max_volume'};
	$Input = $object->{'input'};
	$Distribution = $object->{'distribution_enable'};
	$Link = $object->{'link_control'};
	$Disable = $object->{'disable_flags'};
	//Variablen umwandeln
	$Input1 = ModifyInput($Input);
	$Volume = $Volume / $MaxVolume * 100;	
	//Variablen setzen
	if ($response == 0)	
		{
		if ($Power == 'on')	
			{
			SetValueBoolean ($ID_Power, true);
			SetValueInteger ($ID_Volume, $Volume);
			SetValueBoolean ($ID_Mute, $Mute);
			SetValueInteger ($ID_Eingang, $Input1);
			}
		else 
			{
			SetValueBoolean ($ID_Power, false);
			SetValueInteger ($ID_Eingang, 0);
			}
		}
	}

function SyncNetPlayInfo(){
	global $ID_Power;
	global $ID_Volume;
	global $ID_Mute;
	global $ID_Eingang;
	global $ID_Playback;
	global $ID_Interpret;
	global $ID_Lied;
	global $ID_Album;
	global $ID_Cover;
	global $ID_NetPreset;
	
	global $host;

	$Answer = getNetPlayInfo();
	$object = json_decode($Answer);
	//Werte zuordnen
	$response = $object->{'response_code'};
	$input = $object->{'input'};
	$play_queue_type = $object->{'play_queue_type'};
	$playback = $object->{'playback'};	//Play, Stop, Pause, usw.
	$repeat = $object->{'repeat'};
	$shuffle = $object->{'shuffle'};
	$PlayTime = $object->{'play_time'};
	$TotalTime = $object->{'total_time'};
	$artist = $object->{'artist'}; //Radiostaton auslesen
	$album = $object->{'album'}; //bei Netradio leer ???
	$track = $object->{'track'};	//Infos, z. B. Hörertelefon
	$coverquelle = $object->{'albumart_url'}; //Cover auslesen
	$coverID = $object->{'albumart_id'};
	$USB_Type = $object->{'usb_devicetype'};
	$auto_stopped = $object->{'auto_stopped'};
	$attribute = $object->{'attribute'};
	
	// Werte umwandeln
	if ($repeat == "off") $repeat = false; 	//Repeat ist Integer und kann mehrere Werte annehmen --> Ändern
	else $repeat = true;

	if ($shuffle == "off") $shuffle = false; //Shuffle ist Integer und kann mehrere Werte annehmen --> Ändern
	else $shuffle = true;

	
	$frame1 = "<iframe src=";
	$IP = "http://{$host}";
	#$frame2 = ' width="100%" heigth="780px">/<iframe>';
	$frame2 = ' width="200px" heigth="100%">/<iframe>';
	$Cover = $frame1 .$IP .$coverquelle .$frame2;
	
	$Playback1 = ModifyPlayback($playback);
	
	//Variablen setzen
	if ($response == 0)
		{	
		SetValueInteger ($ID_Playback, $Playback1);
#		SetValueBoolean (47951, $repeat);
#		SetValueBoolean (56074, $shuffle);
		SetValueString ($ID_Interpret, $artist);
		SetValueString ($ID_Lied, $track);
		SetValueString ($ID_Album, $album);
		if ($Cover != GetValue ($ID_Cover))	SetValueString ($ID_Cover, $Cover);
		}	
	}


function SyncPower (){	
	global $ID_Power;	
	$Answer = getStatus();
	$object = json_decode($Answer);
	//Werte zuordnen
	$response = $object->{'response_code'};
	$Power = $object->{'power'};
	//Variablen setzen
	if ($response == 0)	
		{
		if ($Power == 'on')	SetValueBoolean ($ID_Power, true);
		else SetValueBoolean ($ID_Power, false);
		Return ($Power);
		}
	}

##############################################################################################
//Werte umwandeln
function ModifyInput($Input){
	if ($Input == 'net_radio') Return 1;
	elseif ($Input == 'airplay') Return 2;
	elseif ($Input == 'bluetooth') Return 3;
	elseif ($Input == 'server') Return 4;
	elseif ($Input == 'mc_link') Return 5;
	else	Return 0; //Falls anderer Input ausgewählt ist, dann auf Auswahlbutton zurückspringen
	}
	
function ModifyPlayback($Playback){
	if ($Playback == 'previous') Return 0;
	elseif ($Playback == 'play') Return 1;
	elseif ($Playback == 'pause') Return 2;
	elseif ($Playback == 'stop') Return 3;
	elseif ($Playback == 'next') Return 4;
	#else	Return 0; 
	}

##############################################################################################
//-----------------------------------------------
//Kommando senden
function SendCommand($Data){
	global $host;
	$Answer = @Sys_GetURLContent("http://{$host}/YamahaExtendedControl/v1/{$Data}");
	return ($Answer);
}

##############################################################################################


?>

Hallo zusammen.
Habe mal ein MusicCast Modul erstellt und auf GitHub gestellt.
GitHub - mistljo/IPSMusicCast

Soweit funktioniert es bei mir unter Windows und Linux.
Das ganze ist noch recht „Beta“, also bitte Nachsicht haben.

Derzeitige Funktionen:

[ul]
[li]Geräte automatisch im Netz finden. -> Anlegen der Speaker Instanz[/li][li]Standard Funktionen wie, Play, stop, Input Auswahl.[/li][li]Update der Album Infos.[/li][li]Subskription zum Speaker->Immer aktuelle Infos [/li][/ul]

Webansicht:

Installation:
1.) Modul installieren.
2.) Instanz „IPSMusicCast“ hinzufügen
3.) „Get Devices“ in den Eigenschaften der Instanz drücken und hoffen das es keinen Fehler gibt. :slight_smile:

Bitte um Rückmeldung ob alles geht oder was nicht, danke.
Joachim

Coole Sache, werde mal am Wochenende versuchen es zu testen:)

Cool, endlich tut sich was in Sachen Musiccast Modul.
Ich werde es in den nächsten Tagen mal testen, wenn ich mal eine ruhige Minute finde.

gruß garfi

Hallo,

ich habe es mal getestet, bei mir findet das Modul keine Geräte.

gruß garfi

Hast du die letzte Version installiert?
Die MC Geräte müssen im gleichen Subnetz sein. Bei der letzten Version kannst du im Modul die Interface Id mit angeben. Versuch mal 1 oder 2 wenn bei 0 nix geht

Sonst für mal das folgende Script aus. Pfad musst du anpassen. Das schickt einen Multicast request ins Netz und sollte alle Geräte zurückliefen. Wenn nichts schau mal wieviele Netzwerkinterfaces du auf deinem Symcon Server hast.

Ggf vorher den Ordner C:Windows emp\musiccast löschen


<?php
require_once('C:\IP-Symcon\modules\IPSMusicCast\libs\autoload.php');
$musicCastNetwork = new MusicCast\Network;
print_r($musicCastNetwork->getSpeakers());
?>

So ich hab es alles nochmals probiert. Bei dem Script kommt folgende Fehlermeldung:


Fatal error:  Uncaught RuntimeException: No devices found on the current network in C:\IP-Symcon\modules\IPSMusicCast\libs\granddam\php-musiccast-api\src\Network.php:180
Stack trace:
#0 C:\IP-Symcon\scripts\47494.ips.php(4): MusicCast\Network->getSpeakers()
#1 {main}
  thrown in C:\IP-Symcon\modules\IPSMusicCast\libs\granddam\php-musiccast-api\src\Network.php on line 180

Dann weiss ich auch nicht wo das Problem liegt. Wie viele Netzwerkinterfaces hast du auf deinem Symcon Server? Mit „getSpeakers()“ wird einfach ein Multicast ins Netz geschickt. Wenn du mehrere Netzwerkkarten hast, kann es sein das er beim falschen rausgeht. Hast du Windows beim IPS Server?

Moin,

ich teste gerade Dein Music-Cast Modul. Kleine Frage, was muss denn unter Sende-Host eingetragen werden?
Der Empfangs-Host ist mit der IP-Adresse meines IPS ( Raspberry ) schon vorausgefüllt.

Grüße Detlev.

Schreib 127.0.0.1 oder so rein. Ist egal, da keine daten darüber gesendet werden

Hi Leute bin neu hier unterwechs und habe dieses Modul instaliert aber ich bekomme es nicht zulaufen und weis leider nicht wo ich was bei der Instanz eintragen muss könnte mir da jemand helfen würde gerner 3 verstärker (RX-V481D) und 1 (WXC-50) steuern damit

danke schon mal

Hallo zusammen,

wird hier an dem Modul noch weiter gearbeitet? Ich hätte auch großes Interesse daran, da ich einige Yamaha Musiccast Komponenten in Betrieb habe. Leider findet das Modul bei mir auch keine Geräte. Ich bekomme die gleiche Meldung wie garfi35.

Ich habe derzeit wenig Zeit mir das anzuschauen, aber der Code liegt auf Github. Du darfst diesen gerne anschauen und ändern. Lg Joachim

ich bin leider nicht so firm im Programmieren, aber ich schau es mir mal an. Das ist tatsächlich einfach die letzte Sache, die bei mir noch nicht richtig eingebunden ist, was mich natürlich ärgert.

Versuch das einmal, wenn du auch keine Geräte findest versuch einmal mit Wireshark mitzuschauen was rausgeschickt wird.

Die musiccast lib ist übrigend von da:GitHub - grandDam/php-musiccast-api: PHP Wrapper for Yamaha MusicCast API

Also ich bekomme leider die gleiche Fehlermeldung wie „garfi35“. Dein Modul brauch ja einen UDP Socket, richtig? Zumindest hat es bei der Installation meinen KNX UDP Socket herangezogen, was natürlich nicht geht. Daher habe ich einen zweiten UDP Socket eingerichtet, der dann nur für das Musiccast Modul ist. Kann es vielleicht etwas mit den Ports zu tun haben? Habe mal den Port „41100“ TCP freigegeben. Vielleicht ist es auch problematisch, dass Symcon bei mir als Dockerimage auf einem NAS läuft!? Die Scripte vom Anfang laufen bei mir super. Da kann ich schon alle meine Musiccast Geräte ansteuern. Über das Modul würde es mir aber doch besser gefallen, allein wegen der Weiterentwicklung. Denn was mir bei den Scripten noch am meisten fehlt ist die Verlinkung der Geräte untereinander, was ja gerade der Clou des Systems ist. Ich habe das versucht selbst einzubauen, bin daran aber kläglich gescheitert. Das Auslesen der Informationen ging noch einfach, aber das Senden bekomme ich nicht hin.

Was sind denn die richtigen Einstellungen für den UDP Socket? Sende- und Empfangshost ist ja eigentlich klar, aber was ist mit den Ports. Muss das ein spezieller Port sein? Mit Wireshark komme ich leider nicht zurecht. Wenn du mir sagen kannst, welche Info du da benötigst, dann suche ich das gerne raus!

Hallo, ich habe mir das Modul Installiert, die Instanz hinzugefügt aber beim aufrufen kommt folgende Fehlermeldung:

Fehler beim Laden der Konfigurationsform

SyntaxError: JSON.parse: unexected character at line 10 column 2 of the JSON data

Kriege ich es irgenwie hin meinem MusicCast Lautsprecher einfach nur ein zu schalten wenn ich das Licht einschalte.

Also als ereignis dann…