Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ Home Assistant custom integration for controlling AirPlay devices connected to a

## Setup
Search HACS for TuneBlade and download.
Instalation is then via the Integrations Page of Home Assistant.
Installation is then via the Integrations Page of Home Assistant.

Details required;
host and port of the TuneBlade server and device_id of the AirPlay device to be added to Home Assistant. This can be found by entering http://host:port/devices into any browser e.g 112347690@Living Room AirPort Express.
Host and port of the TuneBlade server (if discovery hasn't worked).

The integration will add a simple switch for turning the connection on/off, and a media player which can be used in the same way but can also control volume (from TuneBlade). Either can be removed from the integration options menu.
The integration will add a simple switch for turning the connection on/off, and a media player which can be used in the same way but can also control volume (from TuneBlade).

## Master Volume Control
Create a new device with a device_id of 'Master'.

The Master control setting must be enabled in TuneBlade settings.
The Master control setting must be enabled in TuneBlade settings. If so then a device named 'Master' will be automatically created.

24 changes: 18 additions & 6 deletions custom_components/tuneblade/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,24 @@

async def async_setup_entry(hass, config_entry, async_add_entities):
coordinator = hass.data[DOMAIN][config_entry.entry_id]
entities = [
TuneBladeMediaPlayer(coordinator, device_id, device_data)
for device_id, device_data in coordinator.data.items()
]
_LOGGER.debug("Adding %d media player(s): %s", len(entities), [e.name for e in entities])
async_add_entities(entities, True)
added_ids = set()

async def _update_entities():
new_entities = []
for device_id, device_data in coordinator.data.items():
if device_id not in added_ids:
entity = TuneBladeMediaPlayer(coordinator, device_id, device_data)
new_entities.append(entity)
added_ids.add(device_id)
_LOGGER.debug("Added new media player: %s", device_data.get("name", device_id))
if new_entities:
async_add_entities(new_entities, True)

# Initial add
await _update_entities()

# Register future additions
coordinator.async_add_listener(_update_entities)

class TuneBladeMediaPlayer(CoordinatorEntity, MediaPlayerEntity):
def __init__(self, coordinator, device_id, device_data):
Expand Down
24 changes: 18 additions & 6 deletions custom_components/tuneblade/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@

async def async_setup_entry(hass, entry, async_add_entities):
coordinator = hass.data[DOMAIN][entry.entry_id]
devices = coordinator.data or {}
entities = [
TuneBladeSwitch(coordinator, device_id, device_data)
for device_id, device_data in devices.items()
]
async_add_entities(entities, update_before_add=True)
added_device_ids = set()

async def _update_entities():
new_entities = []
for device_id, device_data in (coordinator.data or {}).items():
if device_id not in added_device_ids:
entity = TuneBladeSwitch(coordinator, device_id, device_data)
new_entities.append(entity)
added_device_ids.add(device_id)
_LOGGER.debug("Added new TuneBlade switch: %s", device_data.get("name", device_id))
if new_entities:
async_add_entities(new_entities)

# Initial add
await _update_entities()

# Track future additions
coordinator.async_add_listener(_update_entities)

class TuneBladeSwitch(CoordinatorEntity, SwitchEntity):
def __init__(self, coordinator, device_id, device_data):
Expand Down
Loading