Python driven Alexa announcements

36 Views Asked by At

I have a python script that runs on my pc, monitors web data and occasionally prints an alert. I would like to feed this string to alexa so the alert ​is announced on all my echo devices. How can I accomplish this?

I know Alexa can accept text because I can type in text via the Alexa android app and have it announced on all my echo devices. I need a way to send text from python scripts to the alexa app and trigger an announcement.

This video at 5:20 (https://youtu.be/UEPt3edhwc0?t=318) shows Echo announcing custom text via Home Assistant, I would like to do this via Python instead. Fortunately Home Assistant uses two python packages, AlexaPy and alexa_media_player, to accomplish this.

AlexaPy (https://alexapy.readthedocs.io/en/latest/alexapy/alexapy.html#submodules) has exactly what I need, a send_announcment method that would allow an echo device to announce text ("this is a test") via the following code snippet.

echo_device = alexapy.AlexaAPI(device, alexa_login) # stuck here
await echo_device.send_announcment(message='this is a test')

I can create the alexa_login object and confirm it works with the following code:

import asyncio
import alexapy

url = 'amazon.com'
name = 'amazon_login_name'
password = 'amazon_password'


def fun_outputpath(file: str):
    return file


async def connect():
    alexa_login = alexapy.AlexaLogin(url, name, password, fun_outputpath)
    await alexa_login.login()
    is_connected = await alexa_login.test_loggedin()
    if is_connected:
        print("Connected")
        print(alexa_login.customer_id)
        print(alexa_login.email)
        print(alexa_login.password)
    else:
        print("Not connected")
    await alexa_login.close()


def main():
    asyncio.run(connect())

if __name__ == "__main__":
    main()

However I cannot figure out what argument to pass as the "device" parameter. Looking through the AlexaPy code shows that device expects a AlexaClient instance.

class AlexaAPI:
    # pylint: disable=too-many-public-methods
    """Class for accessing a specific Alexa device using rest API.

    Args:
    device (AlexaClient): Instance of an AlexaClient to access
    login (AlexaLogin): Successfully logged in AlexaLogin

    """

    devices: dict[str, Any] = {}
    wake_words: dict[str, Any] = {}
    _sequence_queue: dict[Any, list[dict[Any, Any]]] = {}
    _sequence_lock: dict[Any, asyncio.Lock] = {}

    def __init__(self, device, login: AlexaLogin):
        """Initialize Alexa device."""
        self._device = device

The AlexaClient Class is defined in the alexa_media_player python package (https://github.com/keatontaylor/alexa_media_player/blob/dev/custom_components/alexa_media/media_player.py):

class AlexaClient(MediaPlayerDevice, AlexaMedia):
    """Representation of a Alexa device."""

    def __init__(self, device, login, second_account_index=0):
        """Initialize the Alexa device."""
        super().__init__(self, login)

        # Logged in info
        self._authenticated = None
        self._can_access_prime_music = None
        self._customer_email = None
        self._customer_id = None
        self._customer_name = None

        # Device info
        self._device = device

I feel I am close to a solution but I need some help figuring out the best way to create a AlexaClient object to pass as an argument to the "device" parameter.

0

There are 0 best solutions below