Yamaha Musiccast Integration - Add option for changing the "Speaker Pattern"

Please add the option for changing the “Speaker Pattern” in the Yamaha Musiccast integration.

This option is useful for Yamaha AVRs that are able to switch between two different speaker setups (for example: 1 = just front speakers as full range for stereo music; 2 = all speakers with according crossovers + subwoofer).

This option exists in the HACS integration “Yamaha (YNCA)” see screenshot below:

And i have written my own Musiccast integration for the Neeo remote that uses this feature.

So i think adding this to the Musiccast Integration should be fairly easy as this is very well documented in the Basic API discription.

Chapter 4.2. getFeatures:
Check here whether the device supports “speaker pattern”. Look for:

  • system.func_list.speaker_pattern (check if feature exists)
  • system.speaker_pattern_num (get number of possible patterns)
AVR Response for getFeatures
{
	"response_code": 0,
	"system": {
		"func_list": [
			"wired_lan",
			"wireless_lan",
			"wireless_direct",
			"network_standby",
			"network_standby_auto",
			"bluetooth_standby",
			"bluetooth_tx_setting",
			"hdmi_out_1",
			"hdmi_out_2",
			"airplay",
			"disklavier_settings",
			"network_reboot",
			"party_mode",
			"speaker_pattern"
		],
		"zone_num": 4,
		"input_list": [
			{
				"id": "napster",
				"distribution_enable": true,
				"rename_enable": false,
				"account_enable": true,
				"play_info_type": "netusb"
			},
			{
				"id": "spotify",
				"distribution_enable": true,
				"rename_enable": false,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "juke",
				"distribution_enable": true,
				"rename_enable": false,
				"account_enable": true,
				"play_info_type": "netusb"
			},
			{
				"id": "airplay",
				"distribution_enable": false,
				"rename_enable": false,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "mc_link",
				"distribution_enable": false,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "server",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "net_radio",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "bluetooth",
				"distribution_enable": true,
				"rename_enable": false,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "usb",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "netusb"
			},
			{
				"id": "tuner",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "tuner"
			},
			{
				"id": "av1",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "av2",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "av3",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "av4",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "av5",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "av6",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "av7",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "audio1",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "audio2",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "audio3",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "phono",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "v_aux",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			},
			{
				"id": "main_sync",
				"distribution_enable": true,
				"rename_enable": true,
				"account_enable": false,
				"play_info_type": "none"
			}
		],
		"speaker_pattern_num": 2
	},
	"zone": [
		{
			"id": "main",
			"func_list": [
				"power",
				"sleep",
				"volume",
				"mute",
				"sound_program",
				"pure_direct",
				"enhancer",
				"tone_control",
				"dialogue_level",
				"signal_info",
				"prepare_input_change",
				"link_control",
				"link_audio_delay",
				"link_audio_quality",
				"scene",
				"audio_select",
				"cursor",
				"menu",
				"surr_decoder_type",
				"contents_display",
				"actual_volume"
			],
			"input_list": [
				"napster",
				"spotify",
				"juke",
				"airplay",
				"mc_link",
				"server",
				"net_radio",
				"bluetooth",
				"usb",
				"tuner",
				"av1",
				"av2",
				"av3",
				"av4",
				"av5",
				"av6",
				"av7",
				"audio1",
				"audio2",
				"audio3",
				"phono",
				"v_aux"
			],
			"sound_program_list": [
				"munich",
				"vienna",
				"amsterdam",
				"freiburg",
				"royaumont",
				"chamber",
				"village_vanguard",
				"warehouse_loft",
				"cellar_club",
				"roxy_theatre",
				"bottom_line",
				"sports",
				"action_game",
				"roleplaying_game",
				"music_video",
				"recital_opera",
				"standard",
				"spectacle",
				"sci-fi",
				"adventure",
				"drama",
				"mono_movie",
				"2ch_stereo",
				"9ch_stereo",
				"surr_decoder",
				"straight"
			],
			"surr_decoder_type_list": [
				"toggle",
				"dolby_pl2x_movie",
				"dolby_pl2x_music",
				"dolby_pl2x_game",
				"dolby_surround",
				"dts_neural_x",
				"dts_neo6_cinema",
				"dts_neo6_music"
			],
			"tone_control_mode_list": [
				"manual"
			],
			"link_control_list": [
				"speed",
				"standard",
				"stability"
			],
			"link_audio_delay_list": [
				"audio_sync",
				"lip_sync"
			],
			"link_audio_quality_list": [
				"compressed",
				"uncompressed"
			],
			"range_step": [
				{
					"id": "volume",
					"min": 0,
					"max": 161,
					"step": 1
				},
				{
					"id": "tone_control",
					"min": -12,
					"max": 12,
					"step": 1
				},
				{
					"id": "dialogue_level",
					"min": 0,
					"max": 3,
					"step": 1
				},
				{
					"id": "actual_volume_db",
					"min": -80.5,
					"max": 16.5,
					"step": 0.5
				}
			],
			"scene_num": 12,
			"cursor_list": [
				"up",
				"down",
				"left",
				"right",
				"select",
				"return"
			],
			"menu_list": [
				"on_screen",
				"top_menu",
				"menu",
				"option",
				"display"
			],
			"actual_volume_mode_list": [
				"db"
			],
			"audio_select_list": [
				"auto",
				"hdmi",
				"coax_opt",
				"analog",
				"unavailable"
			]
		},
		{
			"id": "zone2",
			"zone_b": false,
			"func_list": [
				"power",
				"sleep",
				"volume",
				"mute",
				"enhancer",
				"tone_control",
				"prepare_input_change",
				"scene",
				"cursor",
				"contents_display",
				"actual_volume"
			],
			"input_list": [
				"napster",
				"spotify",
				"juke",
				"airplay",
				"mc_link",
				"server",
				"net_radio",
				"bluetooth",
				"usb",
				"tuner",
				"av1",
				"av2",
				"av3",
				"av4",
				"av5",
				"av6",
				"av7",
				"audio1",
				"audio2",
				"audio3",
				"phono",
				"v_aux",
				"main_sync"
			],
			"tone_control_mode_list": [
				"manual"
			],
			"range_step": [
				{
					"id": "volume",
					"min": 0,
					"max": 161,
					"step": 1
				},
				{
					"id": "tone_control",
					"min": -12,
					"max": 12,
					"step": 1
				},
				{
					"id": "actual_volume_db",
					"min": -80.5,
					"max": 16.5,
					"step": 0.5
				}
			],
			"scene_num": 4,
			"cursor_list": [
				"up",
				"down",
				"left",
				"right",
				"select",
				"return"
			],
			"actual_volume_mode_list": [
				"db"
			]
		},
		{
			"id": "zone3",
			"func_list": [
				"power",
				"sleep",
				"volume",
				"mute",
				"enhancer",
				"tone_control",
				"prepare_input_change",
				"scene",
				"actual_volume"
			],
			"input_list": [
				"napster",
				"spotify",
				"juke",
				"airplay",
				"mc_link",
				"server",
				"net_radio",
				"bluetooth",
				"usb",
				"tuner",
				"av1",
				"av2",
				"av3",
				"av4",
				"audio1",
				"audio2",
				"audio3",
				"phono",
				"v_aux",
				"main_sync"
			],
			"tone_control_mode_list": [
				"manual"
			],
			"range_step": [
				{
					"id": "volume",
					"min": 0,
					"max": 161,
					"step": 1
				},
				{
					"id": "tone_control",
					"min": -12,
					"max": 12,
					"step": 1
				},
				{
					"id": "actual_volume_db",
					"min": -80.5,
					"max": 16.5,
					"step": 0.5
				}
			],
			"scene_num": 4,
			"actual_volume_mode_list": [
				"db"
			]
		},
		{
			"id": "zone4",
			"func_list": [
				"power",
				"sleep",
				"prepare_input_change",
				"scene"
			],
			"input_list": [
				"av1",
				"av2",
				"av3",
				"av4",
				"av5",
				"av6",
				"av7",
				"v_aux"
			],
			"scene_num": 4
		}
	],
	"tuner": {
		"func_list": [
			"am",
			"fm",
			"rds"
		],
		"range_step": [
			{
				"id": "am",
				"min": 531,
				"max": 1611,
				"step": 9
			},
			{
				"id": "fm",
				"min": 87500,
				"max": 108000,
				"step": 50
			}
		],
		"preset": {
			"type": "common",
			"num": 40
		}
	},
	"netusb": {
		"func_list": [
			"recent_info",
			"play_queue",
			"mc_playlist",
			"streaming_service_use"
		],
		"preset": {
			"num": 40
		},
		"recent_info": {
			"num": 40
		},
		"play_queue": {
			"size": 200
		},
		"mc_playlist": {
			"size": 200,
			"num": 5
		},
		"net_radio_type": "airable",
		"pandora": {
			"sort_option_list": [
				"date",
				"alphabet"
			]
		},
		"siriusxm": {
			"api_type": "everest"
		}
	},
	"distribution": {
		"version": 2.0,
		"compatible_client": [
			2
		],
		"client_max": 9,
		"server_zone_list": [
			"main"
		]
	},
	"ccs": {
		"supported": true
	}
}

Chapter 4.21. getFuncStatus:
Use this for checking the status of the pattern in use. Look for “speaker_pattern”

AVR Response for getFuncStatus
{
	"response_code": 0,
	"hdmi_out_1": true,
	"hdmi_out_2": true,
	"party_mode": false,
	"speaker_pattern": 1
}

Chapter 4.41. setSpeakerPattern:
Use this to set a speaker pattern.

the upstream lib would need to support it before HA can

Reviewing the code of the upstream lib it seems to me, that the feature is already implemented.

I opened an issue in the repo.