Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add restore volume service (#2773) #2776

Merged
merged 1 commit into from
Dec 28, 2024
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
1 change: 1 addition & 0 deletions custom_components/alexa_media/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
DEFAULT_SCAN_INTERVAL = 60

SERVICE_UPDATE_LAST_CALLED = "update_last_called"
SERVICE_RESTORE_VOLUME = "restore_volume"
SERVICE_FORCE_LOGOUT = "force_logout"

RECURRING_PATTERN = {
Expand Down
73 changes: 64 additions & 9 deletions custom_components/alexa_media/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

from alexapy import AlexaAPI, AlexapyLoginError, hide_email
from alexapy.errors import AlexapyConnectionError
from homeassistant.helpers import config_validation as cv
from homeassistant.const import ATTR_DEVICE_ID, ATTR_ENTITY_ID
from homeassistant.helpers import config_validation as cv, entity_registry as er
import voluptuous as vol

from .const import (
Expand All @@ -21,6 +22,7 @@
DATA_ALEXAMEDIA,
DOMAIN,
SERVICE_FORCE_LOGOUT,
SERVICE_RESTORE_VOLUME,
SERVICE_UPDATE_LAST_CALLED,
)
from .helpers import _catch_login_errors, report_relogin_required
Expand All @@ -34,6 +36,7 @@
LAST_CALL_UPDATE_SCHEMA = vol.Schema(
{vol.Optional(ATTR_EMAIL, default=[]): vol.All(cv.ensure_list, [cv.string])}
)
RESTORE_VOLUME_SCHEMA = vol.Schema({vol.Required(ATTR_ENTITY_ID): cv.entity_id})


class AlexaMediaServices:
Expand All @@ -46,31 +49,41 @@ def __init__(self, hass, functions: dict[str, Callable]):

async def register(self):
"""Register services to hass."""
self.hass.services.async_register(
DOMAIN, SERVICE_FORCE_LOGOUT, self.force_logout, schema=FORCE_LOGOUT_SCHEMA
)
self.hass.services.async_register(
DOMAIN,
SERVICE_UPDATE_LAST_CALLED,
self.last_call_handler,
schema=LAST_CALL_UPDATE_SCHEMA,
)
self.hass.services.async_register(
DOMAIN, SERVICE_FORCE_LOGOUT, self.force_logout, schema=FORCE_LOGOUT_SCHEMA
DOMAIN,
SERVICE_RESTORE_VOLUME,
self.restore_volume,
schema=RESTORE_VOLUME_SCHEMA,
)

async def unregister(self):
"""Register services to hass."""
"""Deregister services from hass."""
self.hass.services.async_remove(DOMAIN, SERVICE_FORCE_LOGOUT)
self.hass.services.async_remove(
DOMAIN,
SERVICE_UPDATE_LAST_CALLED,
)
self.hass.services.async_remove(DOMAIN, SERVICE_FORCE_LOGOUT)
self.hass.services.async_remove(
DOMAIN,
SERVICE_RESTORE_VOLUME,
)

@_catch_login_errors
async def force_logout(self, call) -> bool:
"""Handle force logout service request.

Arguments
call.ATTR_EMAIL {List[str: None]} -- Case-sensitive Alexa emails.
Default is all known emails.
call.ATTR_EMAIL {List[str: None]}: List of case-sensitive Alexa emails.
If None, all accounts are logged out.

Returns
bool -- True if force logout successful
Expand All @@ -97,12 +110,13 @@ async def force_logout(self, call) -> bool:
)
return success

@_catch_login_errors
async def last_call_handler(self, call):
"""Handle last call service request.

Args
call: List of case-sensitive Alexa email addresses. If None
all accounts are updated.
Arguments
call.ATTR_EMAIL: {List[str: None]}: List of case-sensitive Alexa emails.
If None, all accounts are updated.

"""
requested_emails = call.data.get(ATTR_EMAIL)
Expand All @@ -121,3 +135,44 @@ async def last_call_handler(self, call):
" check your network connection and try again",
hide_email(email),
)

async def restore_volume(self, call) -> bool:
"""Handle restore volume service request.

Arguments
call.ATTR_ENTITY_ID {str: None} -- Alexa media player entity.

"""
entity_id = call.data.get(ATTR_ENTITY_ID)
_LOGGER.debug("Service restore_volume called for: %s", entity_id)

# Retrieve the entity registry and entity entry
entity_registry = er.async_get(self.hass)
entity_entry = entity_registry.async_get(entity_id)

if not entity_entry:
_LOGGER.error("Entity %s not found in registry", entity_id)
return False

# Retrieve the previous volume from the entity's state attributes
state = self.hass.states.get(entity_id)
if not state or "previous_volume" not in state.attributes:
_LOGGER.error(
"Previous volume attribute not found for entity %s", entity_id
)
return False

previous_volume = state.attributes["previous_volume"]

# Call the volume_set service with the retrieved volume
await self.hass.services.async_call(
domain="media_player",
service="volume_set",
service_data={
"volume_level": previous_volume,
},
target={"entity_id": entity_id},
)

_LOGGER.debug("Volume restored to %s for entity %s", previous_volume, entity_id)
return True
24 changes: 18 additions & 6 deletions custom_components/alexa_media/services.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
# SPDX-License-Identifier: Apache-2.0
update_last_called:
force_logout:
# Description of the service
description: Forces update of last_called echo device for each Alexa account.
description: Force logout of Alexa Login account and deletion of .pickle. Intended for debugging use.
# Different fields that your service accepts
fields:
# Key of the field
email:
# Description of the field
description: List of Alexa accounts to update. If empty, will update all known accounts.
description: List of Alexa accounts to log out. If empty, will log out from all known accounts.
# Example value that can be passed for this field
example: "[email protected]"

force_logout:
restore_volume:
description: Restores an Alexa Media Player volume level to the previous volume level.
fields:
entity_id:
name: Entity
description: Alexa Media Player device to restore volume on.
required: true
selector:
entity:
domain: media_player
integration: alexa_media

update_last_called:
# Description of the service
description: Force logout of Alexa Login account and deletion of .pickle. Intended for debugging use.
description: Forces update of last_called echo device for each Alexa account.
# Different fields that your service accepts
fields:
# Key of the field
email:
# Description of the field
description: List of Alexa accounts to log out. If empty, will log out from all known accounts.
description: List of Alexa accounts to update. If empty, will update all known accounts.
# Example value that can be passed for this field
example: "[email protected]"
10 changes: 10 additions & 0 deletions custom_components/alexa_media/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@
}
}
},
"restore_volume": {
"description": "Restore previous volume level on Alexa media player device",
"fields": {
"entity_id": {
"description": "Entity to restore the previous volume level on",
"name": "Select media player:"
}
},
"name": "Restore Previous Volume"
},
"update_last_called": {
"name": "Update Last Called Sensor",
"description": "Forces update of last_called echo device for each Alexa account.",
Expand Down
24 changes: 10 additions & 14 deletions custom_components/alexa_media/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,6 @@
}
},
"services": {
"clear_history": {
"description": "Clear last entries from Alexa Voice history for each Alexa account.",
"fields": {
"email": {
"description": "Accounts to clear. Empty will clear all.",
"name": "Email address"
},
"entries": {
"description": "Number of entries to clear from 1 to 50. If empty, clear 50.",
"name": "Number of Entries"
}
},
"name": "Clear Amazon Voice History"
},
"force_logout": {
"description": "Force account to logout. Used mainly for debugging.",
"fields": {
Expand All @@ -92,6 +78,16 @@
},
"name": "Force Logout"
},
"restore_volume":{
"description":"Restore previous volume setting on Alexa media player device",
"fields": {
"entity_id": {
"description": "Entity to restore the previous volume level on",
"name": "Select media player:"
}
},
"name":"Restore Previous Volume"
},
"update_last_called": {
"description": "Forces update of last_called echo device for each Alexa account.",
"fields": {
Expand Down
Loading