diff --git a/README.md b/README.md index 1036b70b..9c550431 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ --- -Alexa Actions is a custom skill that coupled with the [Alexa Media Player](https://github.com/custom-components/alexa_media_player/) custom component allows for actionable notificaitons to your Alexa device from Home Assistant. +Alexa Actions is a custom skill that coupled with the [Alexa Media Player](https://github.com/custom-components/alexa_media_player/) custom component allows for actionable notifications to your Alexa device from Home Assistant. ### Getting Started To get started, head over to the [Alexa Actions Wiki](https://github.com/keatontaylor/alexa-actions/wiki). @@ -17,4 +17,10 @@ Thanks to [@alandtse](https://github.com/alandtse) for his continued worked on t If you've found this useful and want to support my sleepless nights: +Creator of Alexa Actions Keaton Taylor: + [![coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/ogFeLZl) + +Contributor and Supporter DeadSec-Security (AKA: Zeus): + +[![coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/zeus500k) diff --git a/lambda/lambda_function.py b/lambda/lambda_function.py index fa5312fd..0a7e6c5f 100644 --- a/lambda/lambda_function.py +++ b/lambda/lambda_function.py @@ -1,7 +1,6 @@ # VERSION 0.8.2 # UPDATE THESE VARIABLES WITH YOUR CONFIG - HOME_ASSISTANT_URL = 'https://yourinstall.com' # REPLACE WITH THE URL FOR YOUR HOME ASSISTANT VERIFY_SSL = True # SET TO FALSE IF YOU DO NOT HAVE VALID CERTS TOKEN = '' # ADD YOUR LONG LIVED TOKEN IF NEEDED OTHERWISE LEAVE BLANK @@ -14,6 +13,7 @@ import json import isodate import prompts +from datetime import datetime from typing import Union, Optional from urllib3 import HTTPResponse @@ -50,6 +50,7 @@ RESPONSE_NUMERIC = "ResponseNumeric" RESPONSE_DURATION = "ResponseDuration" RESPONSE_STRING = "ResponseString" +RESPONSE_DATE_TIME = "ResponseDateTime" class Borg: @@ -388,26 +389,79 @@ def can_handle(self, handler_input): def handle(self, handler_input): """Handle the Date Time intent.""" logger.info('Date Intent Handler triggered') + ha_obj = HomeAssistant(handler_input) - dates = get_slot_value(handler_input, 'Dates') - times = get_slot_value(handler_input, 'Times') + date = get_slot_value(handler_input, 'Dates') + time = get_slot_value(handler_input, 'Times') - logger.debug(f'Dates: {dates}') - logger.debug(f'Times: {times}') + logger.debug(f'Dates: {date} of type {type(date)}') + logger.debug(f'Times: {time} of type {type(time)}') - if not dates and not times: + if not date and not time: raise - data = handler_input.attributes_manager.request_attributes["_"] - speak_output = data[prompts.ERROR_SPECIFIC_DATE] + speak_output = ha_obj.post_ha_event(json.dumps({ + **self._parse_date(date), + **self._parse_time(time) + }), RESPONSE_DATE_TIME) return ( handler_input.response_builder - .speak(speak_output) - .ask('') - .response + .speak(speak_output) + .response ) + @staticmethod + def _parse_date(date: str) -> dict: + date_data = { + 'day': None, + 'month': None, + 'year': None, + } + + if not date: + return date_data + + date = date.split('-') + date_len = len(date) + + date_data['day'] = date[2] if date_len >= 3 else None + date_data['month'] = date[1] if date_len >= 2 else None + date_data['year'] = date[0] if date_len >= 1 else None + + return date_data + + @staticmethod + def _parse_time(time: str) -> dict: + time_data = { + 'seconds': None, + 'minute': None, + 'hour': None, + } + + if not time: + return time_data + + # If the letter s is present then the hole time represents a second + if 's' in time.lower(): + time_data['seconds'] = time.lower().replace('s', '') + return time_data + if 'm' in time.lower(): + time_data['minute'] = time.lower().replace('m', '') + return time_data + if 'h' in time.lower(): + time_data['hour'] = time.lower().replace('h', '') + return time_data + + time = time.split(':') + time_len = len(time) + + time_data['seconds'] = time[2] if time_len >= 3 else None + time_data['minute'] = time[1] if time_len >= 2 else None + time_data['hour'] = time[0] if time_len >= 1 else None + + return time_data + class CancelOrStopIntentHandler(AbstractRequestHandler): """Single handler for Cancel and Stop Intent.""" diff --git a/lambda/language_strings.json b/lambda/language_strings.json index fd916e9a..6dc7bd96 100644 --- a/lambda/language_strings.json +++ b/lambda/language_strings.json @@ -5,7 +5,6 @@ "ERROR_400": "Could not communicate with home assistant. Please check the Amazon CloudWatch logs in the custom skill developer console.", "ERROR_ACOUSTIC": "Sorry I did not catch that... {}", "ERROR_CONFIG": "Sorry, I am having trouble, please check your configuration, in the custom skill and try again.", - "ERROR_SPECIFIC_DATE": "Sorry, I can not do specific dates right now, try a duration instead, like... in 5 hours", "HELP_MESSAGE": "This skill should be only reactively while triggered via home assistant.", "OKAY": "Okay", "STRING" : "You selected {}", @@ -20,7 +19,6 @@ "ERROR_400": "Ich kann keine Verbindung zum home assistant vornehmen. Bitte prüfe die Amazon CloudWatch logdateien in der Alexa Entwickler Console.", "ERROR_ACOUSTIC": "Das habe ich leider nicht verstanden... {}", "ERROR_CONFIG": "Entschuldige, hier ist etwas schief gelaufen. Bitte prüfe deine Konfiugration im custom skill und versuche es erneut.", - "ERROR_SPECIFIC_DATE": "Ich kann leider noch kein spezifisches Datum verarbeiten. Bitte nutze stattedessen Zeiträume wie beispielsweise... in 5 Stunden.", "HELP_MESSAGE": "Dieser Skill sollte nur reaktiv genutzt werden, wenn er via home assistant angestossen wird", "OKAY": "Okay", "STRING" : "Du hast {} gewählt", @@ -35,7 +33,6 @@ "ERROR_400": "Impossible de communiquer avec home assistant. Veuillez verifier les logs Amazon CloudWAtch dans la console de développement de votre skill personnalisé.", "ERROR_ACOUSTIC": "Désolé je n'ai pas compris... {}.", "ERROR_CONFIG": "Désolé, j'ai quelques problèmes, veuillez verifier votre configuration dans votre skill personnalisé et essayez à nouveau.", - "ERROR_SPECIFIC_DATE": "Désolé, je ne peux pas gérer de date specifiques pour le moment. Essayez plutôt avec une période comme par exemple... dans 5 heures", "HELP_MESSAGE": "Cette skill ne devrait être seulement réactive que depuis un appel de home assistant", "OKAY": "Okay", "STRING": "Vous avez choisi {}", @@ -56,7 +53,6 @@ "ERROR_400": "Impossibile accedere ad Home Assistant. Controllare i logs su Amazon CloudWatch nella custom skill developer console.", "ERROR_ACOUSTIC": "Mi dispiace, non ho capito... {}", "ERROR_CONFIG": "Mi dispiace, c'e' qualche problema, per favore controlla la configurazione della custom skill e riprova.", - "ERROR_SPECIFIC_DATE": "Mi dispiace, non riesco a usare date specifiche in questo caso, prova con una data relative, ad esempio... tra 5 ore", "HELP_MESSAGE": "Questa skill dovrebbe rispondere solo quando attivata da Home Assistant.", "OKAY": "Okay", "STRING" : "Hai selezionato {}", @@ -74,7 +70,6 @@ "ERROR_400": "Não consigo me conectar ao Home Assistant. Por favor, cheque os registros no painel de desenvolvimento desta minha habilidade.", "ERROR_ACOUSTIC": "Desculpe, não entendi... {}", "ERROR_CONFIG": "Desculpe, estou com problemas. Por favor, cheque suas configurações nesta minha habilidade e tente novamente.", - "ERROR_SPECIFIC_DATE": "Desculpe, não consigo lidar com datas específicas por enquanto. Tente dizer um intervalo de tempo, por exemplo... em 5 horas", "HELP_MESSAGE": "Essa habilidade deve ser acionada reativamente quando invocada pelo Home Assistant.", "OKAY": "Tudo bem", "STRING": "Você escolheu {}", diff --git a/lambda/prompts.py b/lambda/prompts.py index af23a0ef..9ffd3e6d 100644 --- a/lambda/prompts.py +++ b/lambda/prompts.py @@ -1,14 +1,13 @@ # Alexa Prompts Language Constants -ERROR_401 = "ERROR_401" -ERROR_404 = "ERROR_404" -ERROR_400 = "ERROR_400" -ERROR_ACOUSTIC = "ERROR_ACOUSTIC" -ERROR_CONFIG = "ERROR_CONFIG" -ERROR_SPECIFIC_DATE = "ERROR_SPECIFIC_DATE" -HELP_MESSAGE = "HELP_MESSAGE" -OKAY = "OKAY" -STRING = "STRING" -SELECTED = "SELECTED" -SKILL_NAME = "SKILL_NAME" -STOP_MESSAGE = "STOP_MESSAGE" -WELCOME_MESSAGE = "WELCOME_MESSAGE" +ERROR_401 = 'ERROR_401' +ERROR_404 = 'ERROR_404' +ERROR_400 = 'ERROR_400' +ERROR_ACOUSTIC = 'ERROR_ACOUSTIC' +ERROR_CONFIG = 'ERROR_CONFIG' +HELP_MESSAGE = 'HELP_MESSAGE' +OKAY = 'OKAY' +STRING = 'STRING' +SELECTED = 'SELECTED' +SKILL_NAME = 'SKILL_NAME' +STOP_MESSAGE = 'STOP_MESSAGE' +WELCOME_MESSAGE = 'WELCOME_MESSAGE'