Skip to content

Commit

Permalink
fixed sound mode issue. added stand positions
Browse files Browse the repository at this point in the history
  • Loading branch information
giachello committed Jan 26, 2025
1 parent f946308 commit 1ad7cd5
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 9 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ beoplay.beoplay_add_media_to_queue:
```
This command is experimental. It allows to add a URL of a DLNA asset on your network to the speaker and play it. Let me know if it works for you!

```
beoplay.beoplay_set_stand_position:
```
This command is experimental. It allows to set the stand position of the TV. This would be the same name you have in your TV configuration, e.g. "StandBy" or "Start-Up".

These are called through service calls, e.g.:

![image](https://user-images.githubusercontent.com/60585229/211130163-81149354-1f41-4ae1-bbd3-1b91bfdcb812.png)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/beoplay/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
"iot_class": "local_push",
"issue_tracker": "https://github.com/giachello/beoplay/issues",
"requirements": [
"pybeoplay==2.4.0"
"pybeoplay==2.6.0"
],
"ssdp": [],
"version": "2024.12.3",
"version": "2025.1.1",
"zeroconf": ["_beoremote._tcp.local."]
}
43 changes: 43 additions & 0 deletions custom_components/beoplay/media_player.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Support for Bang & Olufsen BeoPlay speakers for Home Assistant.
This file provides a Media Player interface to Bang & Olufsen devices using the BeoPlay interface.
Key features:
Expand Down Expand Up @@ -28,6 +29,7 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_ID,
CONF_URL,
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP,
Expand Down Expand Up @@ -85,6 +87,7 @@
BEOPLAY_EXPERIENCE_JOIN_SERVICE = "beoplay_join_experience"
BEOPLAY_EXPERIENCE_LEAVE_SERVICE = "beoplay_leave_experience"
BEOPLAY_ADD_MEDIA_SERVICE = "beoplay_add_media_to_queue"
BEOPLAY_SET_STAND_POSITION = "beoplay_set_stand_position"

EXPERIENCE_SCHEMA = vol.Schema(
{
Expand All @@ -99,6 +102,13 @@
}
)

SET_STAND_POSITION_SCHEMA = vol.Schema(
{
vol.Required(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(CONF_ID): cv.string,
}
)

BEOPLAY_POLL_TASK = "BeoPlay Poll Task"

ENTITY_ID_FORMAT = DOMAIN + ".{}"
Expand Down Expand Up @@ -152,6 +162,18 @@ def add_media(service: ServiceDataType):
for entity in entities:
entity.add_media(url)

def set_stand_positions(service: ServiceDataType):
"""Join to an existing experience."""
_LOGGER.debug("Get Positions service called")
entity_ids = service.data.get("entity_id")
id = service.data.get("id")
entities = hass.data[DATA_BEOPLAY].entities

if entity_ids:
entities = [e for e in entities if e.entity_id in entity_ids]
for entity in entities:
entity.set_stand_position(id)

# the callbacks for starting / stopping the polling (Notifications) task
@callback
def _start_polling(event=None):
Expand Down Expand Up @@ -183,6 +205,13 @@ def _stop_polling(event=None):
schema=ADD_MEDIA_SCHEMA,
)

hass.services.async_register(
DOMAIN,
BEOPLAY_SET_STAND_POSITION,
set_stand_positions,
schema=SET_STAND_POSITION_SCHEMA,
)

hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _stop_polling)

speaker = BeoPlay(hass, api, type)
Expand Down Expand Up @@ -440,6 +469,14 @@ def app_name(self):
"""Name of the current running app."""
return self.source

@property
def extra_state_attributes(self):
"""Return the state attributes (stand positions)."""
attributes = {}
attributes["stand_positions"] = self._speaker.standPositions
attributes["stand_position"] = self._speaker.standPosition
return attributes

# ========== Service Calls ==========

def turn_on(self):
Expand Down Expand Up @@ -515,6 +552,10 @@ def add_media(self, url):
}
self._speaker.playQueueItem(False, item)

def set_stand_position(self, id):
"""Set the stand position."""
self._speaker.setStandPosition(id)

@Throttle(MIN_TIME_BETWEEN_UPDATES)
async def async_update(self):
"""Get the latest data and update device state."""
Expand All @@ -536,6 +577,8 @@ async def async_update(self):
)
await self._speaker.async_get_sources()
await self._speaker.async_get_sound_modes()
await self._speaker.async_get_stand_positions()
await self._speaker.async_get_stand_position()
self._first_run = False
except (ClientError, ClientConnectorError):
_LOGGER.error(
Expand Down
26 changes: 19 additions & 7 deletions custom_components/beoplay/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,37 @@ beoplay_join_experience:
fields:
entity_id:
name: "B&O Media player"
description: "A media player Entity ID."
example: "media_player.my_chromecast"
description: "A beoplay Entity ID."
example: "media_player.my_beo_device"
beoplay_leave_experience:
name: "Leave Experience"
description: "Leave the current playback experience."
fields:
entity_id:
name: "B&O Media player"
description: "A media player Entity ID."
example: "media_player.my_chromecast"
description: "A beoplay Entity ID."
example: "media_player.my_beo_device"
beoplay_add_media_to_queue:
name: "Add to playback Queue"
description: "Add media to the current playback queue. This is untested. Please report back if it works."
fields:
entity_id:
name: "B&O Media player"
description: "A media player Entity ID."
example: "media_player.my_beosound"
description: "A beoplay Entity ID."
example: "media_player.my_beo_device"
url:
name: "Media URL"
description: "A URL to add to the playback queue. Must be reachable from the speaker."
example: "http://192.168.1.1/DLNAfile.mp3"
example: "http://192.168.1.1/DLNAfile.mp3"
beoplay_set_stand_position:
name: "Set Stand Position"
description: "Set the B&O TV stand position."
fields:
entity_id:
name: "B&O Media player"
description: "A beoplay Entity ID."
example: "media_player.my_beo_device"
id:
name: "Stand position"
description: "The stand position name, as configured on the TV."
example: "Start-up"

0 comments on commit 1ad7cd5

Please sign in to comment.