From 44ed7d1e529c80505fdb339f8ddc5cd19730d6b8 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:22:34 -0700 Subject: [PATCH] Implement alert message handler (#57) # Description Adds support for expired alert messages from Neon # Issues # Other Notes The current implementation only logs a message that the alert expired and will not mark it as missed; the alert will remain active until the user dismisses it via intent. This behavior is all delegated to the client, so it may be worth adding some utility methods to the base class for specific clients to more easily interact with received alerts. --------- Co-authored-by: Daniel McKnight --- neon_iris/client.py | 11 +++++++++++ neon_iris/web_client.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/neon_iris/client.py b/neon_iris/client.py index 62f8db7..2faa7c1 100644 --- a/neon_iris/client.py +++ b/neon_iris/client.py @@ -179,6 +179,8 @@ def handle_neon_response(self, channel, method, _, body): self.handle_error_response(message) elif message.msg_type == "neon.languages.get.response": self._handle_supported_languages(message) + elif message.msg_type == "neon.alert_expired": + self.handle_alert(message) elif message.msg_type.endswith(".response"): self.handle_api_response(message) else: @@ -231,6 +233,12 @@ def clear_media(self, message: Message): Override this method to handle requests to clear media (photos, etc) """ + @abstractmethod + def handle_alert(self, message: Message): + """ + Override this method to handle alerts (timers, alarms, reminders) + """ + def _handle_profile_update(self, message: Message): updated_profile = message.data["profile"] if updated_profile['user']['username'] == \ @@ -469,6 +477,9 @@ def handle_api_response(self, message: Message): def clear_caches(self, message: Message): print("Cached Responses Cleared") + def handle_alert(self, message: Message): + print(f"\nAlert Expired: {message.data.get('alert_name')}") + def clear_media(self, message: Message): pass diff --git a/neon_iris/web_client.py b/neon_iris/web_client.py index d2bfc55..a9f9e3d 100644 --- a/neon_iris/web_client.py +++ b/neon_iris/web_client.py @@ -50,6 +50,7 @@ def __init__(self, lang: str = None): self.config = config.get('iris') or dict() NeonAIClient.__init__(self, config.get("MQ")) self._await_response = Event() + self._alerts = dict() self._response = None self._transcribed = None self._current_tts = dict() @@ -80,6 +81,14 @@ def _start_session(self): self._profiles[sid]['user']['username'] = sid return sid + def check_alerts(self, session_id: str): + if not self._alerts.get(session_id): + gradio.Info("No Alerts") + return session_id + while self._alerts.get(session_id): + gradio.Info(self._alerts[session_id].pop()) + return session_id + def update_profile(self, stt_lang: str, tts_lang: str, tts_lang_2: str, time: int, date: str, uom: str, city: str, state: str, country: str, first: str, middle: str, last: str, @@ -214,6 +223,9 @@ def run(self): # inputs=[client_session], # outputs=[tts_audio, client_session]) # Define settings UI + with gradio.Row(): + submit = gradio.Button("Update User Settings") + check_alerts = gradio.Button("Check for Alerts") with gradio.Row(): with gradio.Column(): lang = self.get_lang(client_session.value).split('-')[0] @@ -253,14 +265,15 @@ def run(self): pref_name = gradio.Textbox(label="Preferred Name") email_addr = gradio.Textbox(label="Email Address") # TODO: DoB, pic, about, phone? - submit = gradio.Button("Update User Settings") submit.click(self.update_profile, inputs=[stt_lang, tts_lang, tts_lang_2, time_format, date_format, unit_of_measure, city, state, country, first_name, middle_name, last_name, pref_name, email_addr, client_session], outputs=[client_session]) - blocks.launch(server_name=address, server_port=port) + check_alerts.click(self.check_alerts, inputs=[client_session], + outputs=[client_session]) + blocks.queue().launch(server_name=address, server_port=port) def handle_klat_response(self, message: Message): """ @@ -307,6 +320,17 @@ def handle_api_response(self, message: Message): if message.msg_type == "neon.audio_input.response": self._transcribed = message.data.get("transcripts", [""])[0] + def handle_alert(self, message: Message): + """ + Handle an expired alert that was previously set by this session. + @param message: neon.alert_expired Message + """ + user = message.context['username'] + LOG.info(f"Alert expired for user: {user}") + alert = f"Alert Expired: {message.data.get('alert_name')}" + self._alerts.setdefault(user, list()) + self._alerts[user].append(alert) + def _handle_profile_update(self, message: Message): updated_profile = message.data["profile"] session_id = updated_profile['user']['username']