Skip to content

Commit

Permalink
[ 1.0.3 ] - 2023/10/30
Browse files Browse the repository at this point in the history
  *  Added "play_url" service support that allows better support for playing URL media content.
  • Loading branch information
thlucas1 committed Oct 30, 2023
1 parent 1d063cd commit 355eccd
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Change are listed in reverse chronological order (newest to oldest).

<span class="changelog">

###### [ 1.0.3 ] - 2023/10/30

* Added "play_url" service support that allows better support for playing URL media content.

###### [ 1.0.2 ] - 2023/10/30

* Removed some HTML formatting from strings.json to be HASSFest validation compliant.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ target:
The following custom services are also supplied by this integration.
- Play Handoff: Handoff playing source from one SoundTouch device to another.
- Play TTS Message: Play Text-To-Speech notification on a SoundTouch device. Note that this is limited to ST10,20,30 devices, as Bose ST300 does not support notifications (AFAIK).
- Play URL: Play media content URL on a SoundTouch device. Note that this is limited to ST10,20,30 devices, as Bose ST300 does not support notifications (AFAIK).
- Get Preset List: Retrieves the list of presets defined to the device.
- Get Recent List: Retrieves the list of recently played items defined to the device.
- Remote Keypress: Simulates the press and release of a key on the SoundTouch device remote control.
Expand Down
33 changes: 32 additions & 1 deletion custom_components/soundtouchplus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
DOMAIN,
SERVICE_PLAY_HANDOFF,
SERVICE_PLAY_TTS,
SERVICE_PLAY_URL,
SERVICE_PRESETLIST,
SERVICE_RECENTLIST,
SERVICE_REMOTE_KEYPRESS,
Expand Down Expand Up @@ -89,12 +90,24 @@
vol.Optional("album"): cv.string,
vol.Optional("track"): cv.string,
vol.Optional("tts_url"): cv.string,
vol.Optional("artist"): cv.string,
vol.Optional("volume_level", default=0): vol.All(vol.Range(min=0,max=100)),
vol.Optional("app_key"): cv.string
}
)

SERVICE_PLAY_URL_SCHEMA = vol.Schema(
{
vol.Required("entity_id"): cv.entity_id,
vol.Required("url"): cv.string,
vol.Optional("artist"): cv.string,
vol.Optional("album"): cv.string,
vol.Optional("track"): cv.string,
vol.Optional("volume_level", default=0): vol.All(vol.Range(min=0,max=100)),
vol.Optional("app_key"): cv.string,
vol.Required("get_metadata_from_url_file", default=False): cv.boolean
}
)

SERVICE_PRESETLIST_SCHEMA = vol.Schema(
{
vol.Required("entity_id"): cv.entity_id,
Expand Down Expand Up @@ -201,6 +214,16 @@ async def service_handle_entity(service:ServiceCall) -> None:
app_key = service.data.get("app_key")
await hass.async_add_executor_job(player.play_tts, message, artist, album, track, tts_url, volume_level, app_key)

elif service.service == SERVICE_PLAY_URL:
url = service.data.get("url")
artist = service.data.get("artist")
album = service.data.get("album")
track = service.data.get("track")
volume_level = service.data.get("volume_level")
app_key = service.data.get("app_key")
get_metadata_from_url_file = service.data.get("get_metadata_from_url_file")
await hass.async_add_executor_job(player.play_url, url, artist, album, track, volume_level, app_key, get_metadata_from_url_file)

else:
_logsi.LogError(STAppMessages.MSG_SERVICE_REQUEST_UNKNOWN, service.service, "service_handle_entity")
return
Expand Down Expand Up @@ -368,6 +391,14 @@ def _GetEntityFromServiceData(hass:HomeAssistant, service:ServiceCall, field_id:
schema=SERVICE_PLAY_TTS_SCHEMA,
)

_logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_PLAY_URL, SERVICE_PLAY_URL_SCHEMA)
hass.services.async_register(
DOMAIN,
SERVICE_PLAY_URL,
service_handle_entity,
schema=SERVICE_PLAY_URL_SCHEMA,
)

_logsi.LogObject(SILevel.Verbose, STAppMessages.MSG_SERVICE_REQUEST_REGISTER % SERVICE_PRESETLIST, SERVICE_PRESETLIST_SCHEMA)
hass.services.async_register(
DOMAIN,
Expand Down
1 change: 1 addition & 0 deletions custom_components/soundtouchplus/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# custom service names.
SERVICE_PLAY_HANDOFF = "play_handoff"
SERVICE_PLAY_TTS = "play_tts"
SERVICE_PLAY_URL = "play_url"
SERVICE_PRESETLIST = "preset_list"
SERVICE_RECENTLIST = "recent_list"
SERVICE_REMOTE_KEYPRESS = "remote_keypress"
Expand Down
2 changes: 1 addition & 1 deletion custom_components/soundtouchplus/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
"smartinspectPython>=3.0.26",
"bosesoundtouchapi>=1.0.3"
],
"version": "1.0.2",
"version": "1.0.3",
"zeroconf": [ "_soundtouch._tcp.local." ]
}
57 changes: 48 additions & 9 deletions custom_components/soundtouchplus/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -843,18 +843,57 @@ def play_tts(self, message:str, artist:str, album:str, track:str, ttsUrl:str, vo
appKey (str):
Bose Developer API application key.
"""
parms:dict = {}
parms['message'] = message
parms['artist'] = artist
parms['album'] = album
parms['track'] = track
parms['ttsUrl'] = ttsUrl
parms['volumeLevel'] = volumeLevel
parms['appKey'] = appKey
_logsi.LogDictionary(SILevel.Verbose, STAppMessages.MSG_PLAYER_COMMAND % ("play_tts", self.name, self.entity_id), parms)
if _logsi.IsOn(SILevel.Verbose):
parms:dict = {}
parms['message'] = message
parms['artist'] = artist
parms['album'] = album
parms['track'] = track
parms['ttsUrl'] = ttsUrl
parms['volumeLevel'] = volumeLevel
parms['appKey'] = appKey
_logsi.LogDictionary(SILevel.Verbose, STAppMessages.MSG_PLAYER_COMMAND % ("play_tts", self.name, self.entity_id), parms)

self._client.PlayNotificationTTS(message, ttsUrl, artist, album, track, volumeLevel, appKey)


def play_url(self, url:str, artist:str, album:str, track:str, volumeLevel:int, appKey:str, getMetadataFromUrlFile:bool):
"""
Play media content from a URL on a SoundTouch device.
Args:
url (str):
The URL media content to play on the device.
artist (str):
The text that will appear in the NowPlaying Artist node; if omitted, default is "Unknown Artist".
album (str):
The text that will appear in the NowPlaying Album node; if omitted, default is "Unknown Album".
track (str):
The text that will appear in the NowPlaying Track node; if omitted, default is "Unknown Track".
volumeLevel (int):
The temporary volume level that will be used when the media is played.
Specify a value of zero to play at the current volume.
Default is zero.
appKey (str):
Bose Developer API application key.
getMetadataFromUrlFile (bool):
The Text-To-Speech url used to translate the message. The value should contain a "{saytext}" format parameter,
that will be used to insert the encoded message text.
"""
if _logsi.IsOn(SILevel.Verbose):
parms:dict = {}
parms['url'] = url
parms['artist'] = artist
parms['album'] = album
parms['track'] = track
parms['volumeLevel'] = volumeLevel
parms['appKey'] = appKey
parms['getMetadataFromUrlFile'] = getMetadataFromUrlFile
_logsi.LogDictionary(SILevel.Verbose, STAppMessages.MSG_PLAYER_COMMAND % ("play_url", self.name, self.entity_id), parms)

self._client.PlayUrl(url, artist, album, track, volumeLevel, appKey, getMetadataFromUrlFile)


def preset_list(self) -> PresetList:
"""
Retrieves the list of presets defined for a device.
Expand Down
68 changes: 68 additions & 0 deletions custom_components/soundtouchplus/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,74 @@ play_tts:
selector:
text:

play_url:
name: Play URL Media
description: Play media content from a URL on a SoundTouch device.
fields:
entity_id:
name: Entity ID
description: Entity ID of the SoundTouch device to play the media.
example: "media_player.soundtouch_livingroom"
required: true
selector:
entity:
integration: soundtouchplus
domain: media_player
url:
name: URL
description: The url to play; value must start with http or https.
example: "https://freetestdata.com/wp-content/uploads/2021/09/Free_Test_Data_1MB_MP3.mp3"
required: true
selector:
text:
artist:
name: Artist Status Text
description: The message text that will appear in the NowPlaying Artist node; if omitted, default is "Unknown Artist".
example: "FreeTestData.com"
required: false
selector:
text:
album:
name: Album Status Text
description: The message text that will appear in the NowPlaying Album node; if omitted, default is "Unknown Album".
example: "MP3 Test Data"
required: false
selector:
text:
track:
name: Track Status Text
description: The message text that will appear in the NowPlaying Track node; if omitted, default is "Unknown Track".
example: "Free_Test_Data_1MB_MP3"
required: false
selector:
text:
volume_level:
name: Volume Level
description: The temporary volume level that will be used when the media is played. Specify a value of zero to play at the current volume. Default is zero.
example: 50
required: false
selector:
number:
min: 0
max: 100
step: 5
unit_of_measurement: "%"
mode: slider
app_key:
name: Bose App Key
description: Bose Developer API application key; if omitted, defaults to a pre-defined App Developer Key.
example: "abcdefghijklmnopqrstuvwxyz"
required: false
selector:
text:
get_metadata_from_url_file:
name: Get Metadata From URL?
description: If true, the artist, album, and song title metadata details will be retrieved from the ID3 header of the url content (if available); otherwise, False to use the artist, album, and song title arguments specified.
example: "false"
required: false
selector:
boolean:

preset_list:
name: Get Preset List
description: Retrieves the list of presets defined to the device.
Expand Down
76 changes: 76 additions & 0 deletions custom_components/soundtouchplus/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,82 @@
}
}
},
"play_tts": {
"name": "Play TTS Message",
"description": "Play Text-To-Speech notification on a SoundTouch device. Note that this is limited to ST10,20,30 devices, as Bose ST300 does not support notifications (AFAIK).",
"fields": {
"entity_id": {
"name": "Entity ID",
"description": "Entity ID of the SoundTouch device to play the message."
},
"message": {
"name": "Message Text",
"description": "The message that will be converted from text to speech and played on the device."
},
"artist": {
"name": "Artist Status Text",
"description": "The text that will appear in the NowPlaying Artist node; if omitted, default is \"TTS Notification\"."
},
"album": {
"name": "Album Status Text",
"description": "The text that will appear in the NowPlaying Album node; if omitted, default is \"Google TTS\"."
},
"track": {
"name": "Track Status Text",
"description": "The text that will appear in the NowPlaying Track node; if omitted, default is the message value."
},
"tts_url": {
"name": "TTS Service Url",
"description": "The Text-To-Speech url used to translate the message. The value should contain a \"{saytext}\" format parameter, that will be used to insert the encoded message text."
},
"volume_level": {
"name": "Volume Level",
"description": "The temporary volume level that will be used when the media is played. Specify a value of zero to play at the current volume. Default is zero."
},
"app_key": {
"name": "Bose App Key",
"description": "Bose Developer API application key; if omitted, defaults to a pre-defined App Developer Key."
}
}
},
"play_url": {
"name": "Play URL Media",
"description": "Play media content from a URL on a SoundTouch device.",
"fields": {
"entity_id": {
"name": "Entity ID",
"description": "Entity ID of the SoundTouch device to play the media."
},
"url": {
"name": "URL",
"description": "The url to play; value must start with http or https."
},
"artist": {
"name": "Artist Status Text",
"description": "The text that will appear in the NowPlaying Artist node; if omitted, default is \"Unknown Artist\"."
},
"album": {
"name": "Album Status Text",
"description": "The text that will appear in the NowPlaying Album node; if omitted, default is \"Unknown Album\"."
},
"track": {
"name": "Track Status Text",
"description": "The text that will appear in the NowPlaying Track node; if omitted, default is \"Unknown Track\"."
},
"volume_level": {
"name": "Volume Level",
"description": "The temporary volume level that will be used when the media is played. Specify a value of zero to play at the current volume. Default is zero."
},
"app_key": {
"name": "Bose App Key",
"description": "Bose Developer API application key; if omitted, defaults to a pre-defined App Developer Key."
},
"get_metadata_from_url_file": {
"name": "Get Metadata From URL?",
"description": "If true, the artist, album, and song title metadata details will be retrieved from the ID3 header of the url content (if available); otherwise, False to use the artist, album, and song title arguments specified."
}
}
},
"preset_list": {
"name": "Get Preset List",
"description": "Retrieves the list of presets defined to the device.",
Expand Down
Loading

0 comments on commit 355eccd

Please sign in to comment.