mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 02:07:54 +00:00
Fix detection of zone master in soundtouch media_player (#33157)
This commit is contained in:
parent
0186ce7896
commit
01bf4daf37
@ -437,15 +437,25 @@ class SoundTouchDevice(MediaPlayerDevice):
|
||||
# slaves for some reason. To compensate for this shortcoming we have to fetch
|
||||
# the zone info from the master when the current device is a slave until this is
|
||||
# fixed in the SoundTouch API or libsoundtouch, or of course until somebody has a
|
||||
# better idea on how to fix this
|
||||
if zone_status.is_master:
|
||||
# better idea on how to fix this.
|
||||
# In addition to this shortcoming, libsoundtouch seems to report the "is_master"
|
||||
# property wrong on some slaves, so the only reliable way to detect if the current
|
||||
# devices is the master, is by comparing the master_id of the zone with the device_id
|
||||
if zone_status.master_id == self._device.config.device_id:
|
||||
return self._build_zone_info(self.entity_id, zone_status.slaves)
|
||||
|
||||
master_instance = self._get_instance_by_ip(zone_status.master_ip)
|
||||
master_zone_status = master_instance.device.zone_status()
|
||||
return self._build_zone_info(
|
||||
master_instance.entity_id, master_zone_status.slaves
|
||||
)
|
||||
# The master device has to be searched by it's ID and not IP since libsoundtouch / BOSE API
|
||||
# do not return the IP of the master for some slave objects/responses
|
||||
master_instance = self._get_instance_by_id(zone_status.master_id)
|
||||
if master_instance is not None:
|
||||
master_zone_status = master_instance.device.zone_status()
|
||||
return self._build_zone_info(
|
||||
master_instance.entity_id, master_zone_status.slaves
|
||||
)
|
||||
|
||||
# We should never end up here since this means we haven't found a master device to get the
|
||||
# correct zone info from. In this case, assume current device is master
|
||||
return self._build_zone_info(self.entity_id, zone_status.slaves)
|
||||
|
||||
def _get_instance_by_ip(self, ip_address):
|
||||
"""Search and return a SoundTouchDevice instance by it's IP address."""
|
||||
@ -454,6 +464,13 @@ class SoundTouchDevice(MediaPlayerDevice):
|
||||
return instance
|
||||
return None
|
||||
|
||||
def _get_instance_by_id(self, instance_id):
|
||||
"""Search and return a SoundTouchDevice instance by it's ID (aka MAC address)."""
|
||||
for instance in self.hass.data[DATA_SOUNDTOUCH]:
|
||||
if instance and instance.device.config.device_id == instance_id:
|
||||
return instance
|
||||
return None
|
||||
|
||||
def _build_zone_info(self, master, zone_slaves):
|
||||
"""Build the exposed zone attributes."""
|
||||
slaves = []
|
||||
|
@ -33,6 +33,8 @@ from homeassistant.setup import async_setup_component
|
||||
|
||||
DEVICE_1_IP = "192.168.0.1"
|
||||
DEVICE_2_IP = "192.168.0.2"
|
||||
DEVICE_1_ID = 1
|
||||
DEVICE_2_ID = 2
|
||||
|
||||
|
||||
def get_config(host=DEVICE_1_IP, port=8090, name="soundtouch"):
|
||||
@ -60,20 +62,22 @@ def one_device_fixture():
|
||||
def two_zones_fixture():
|
||||
"""Mock one master and one slave."""
|
||||
device_1 = MockDevice(
|
||||
DEVICE_1_ID,
|
||||
MockZoneStatus(
|
||||
is_master=True,
|
||||
master_id=1,
|
||||
master_id=DEVICE_1_ID,
|
||||
master_ip=DEVICE_1_IP,
|
||||
slaves=[MockZoneSlave(DEVICE_2_IP)],
|
||||
)
|
||||
),
|
||||
)
|
||||
device_2 = MockDevice(
|
||||
DEVICE_2_ID,
|
||||
MockZoneStatus(
|
||||
is_master=False,
|
||||
master_id=1,
|
||||
master_id=DEVICE_1_ID,
|
||||
master_ip=DEVICE_1_IP,
|
||||
slaves=[MockZoneSlave(DEVICE_2_IP)],
|
||||
)
|
||||
),
|
||||
)
|
||||
devices = {DEVICE_1_IP: device_1, DEVICE_2_IP: device_2}
|
||||
device_patch = patch(
|
||||
@ -112,9 +116,9 @@ async def setup_soundtouch(hass, config):
|
||||
class MockDevice(STD):
|
||||
"""Mock device."""
|
||||
|
||||
def __init__(self, zone_status=None):
|
||||
def __init__(self, id=None, zone_status=None):
|
||||
"""Init the class."""
|
||||
self._config = MockConfig()
|
||||
self._config = MockConfig(id)
|
||||
self._zone_status = zone_status or MockZoneStatus()
|
||||
|
||||
def zone_status(self, refresh=True):
|
||||
@ -125,9 +129,10 @@ class MockDevice(STD):
|
||||
class MockConfig(Config):
|
||||
"""Mock config."""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, id=None):
|
||||
"""Init class."""
|
||||
self._name = "name"
|
||||
self._id = id or DEVICE_1_ID
|
||||
|
||||
|
||||
class MockZoneStatus(ZoneStatus):
|
||||
|
Loading…
x
Reference in New Issue
Block a user