Automated Voice Assistant for Elderly Care with Emergency Detection Python

👤 Sharing: AI
```python
import speech_recognition as sr
import pyttsx3
import datetime
import time
import threading
import warnings

# Suppress warnings to keep the output cleaner.  Useful for demo purposes.
warnings.filterwarnings("ignore")

# ---- Emergency Keywords and Actions ----
EMERGENCY_KEYWORDS = ["help", "emergency", "fall", "hurt", "pain"]
EMERGENCY_CONTACT = "123-456-7890"  # Replace with actual emergency contact number
FALL_DETECTION_THRESHOLD = 2  # Simple example: If "fall" or "hurt" are repeated this many times quickly, assume fall

# ---- Assistant Configuration ----
ASSISTANT_NAME = "ElderCare Assistant"  # Feel free to change this
WAKE_WORD = "hey assistant"  # Word to activate the assistant

# ---- TTS (Text-to-Speech) Engine Setup ----
engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[1].id)  # Use a female voice (index 1 - might vary depending on your system)
engine.setProperty('rate', 150)  # Adjust speech rate (words per minute)


# ---- Speech Recognition Setup ----
recognizer = sr.Recognizer()
microphone = sr.Microphone()


# ---- Global Variables for Emergency Detection ----
emergency_count = 0
last_emergency_time = None
emergency_lock = threading.Lock()  # Lock to prevent race conditions in the emergency handling


# ---- Functions ----

def speak(text):
    """Speaks the given text using the TTS engine."""
    print(f"{ASSISTANT_NAME}: {text}")  # Display what the assistant is saying
    engine.say(text)
    engine.runAndWait()



def listen():
    """Listens for user input and returns the recognized text."""
    with microphone as source:
        recognizer.adjust_for_ambient_noise(source)  # Calibrate for noise
        print("Listening...")
        audio = recognizer.listen(source)

    try:
        text = recognizer.recognize_google(audio)
        print(f"You said: {text}")
        return text.lower()  # Convert to lowercase for easier processing
    except sr.UnknownValueError:
        print("Sorry, I could not understand.")
        return ""
    except sr.RequestError as e:
        print(f"Could not request results from Google Speech Recognition service; {e}")
        return ""



def get_time():
    """Returns the current time."""
    now = datetime.datetime.now()
    return now.strftime("%I:%M %p")  # Formats time as 02:30 PM



def get_date():
    """Returns the current date."""
    now = datetime.datetime.now()
    return now.strftime("%B %d, %Y")  # Formats date as January 01, 2024



def handle_emergency():
    """Handles emergency situations."""
    global emergency_count, last_emergency_time

    with emergency_lock: # Aquire the lock
        current_time = datetime.datetime.now()

        if last_emergency_time and (current_time - last_emergency_time).total_seconds() < 10: # Check if last emergency was within the last 10 seconds
            emergency_count += 1
        else:
            emergency_count = 1

        last_emergency_time = current_time


        if emergency_count >= FALL_DETECTION_THRESHOLD:
            speak("Emergency detected!  Calling emergency contact.")
            # Simulate calling the emergency contact (replace with actual call functionality)
            print(f"Calling {EMERGENCY_CONTACT}...")
            speak(f"Simulating a call to {EMERGENCY_CONTACT}.  This is a simulated emergency call. Do not be alarmed.")
            # You'd implement actual calling functionality here (e.g., using Twilio).
            emergency_count = 0 # Reset count after action is taken
        else:
            speak("Are you okay? I detected you might need assistance.")



def process_command(command):
    """Processes the user's command."""
    global emergency_count, last_emergency_time

    if any(keyword in command for keyword in EMERGENCY_KEYWORDS):
        handle_emergency()
        return  # Stop further processing after emergency handling

    if "what time is it" in command or "tell me the time" in command:
        time_str = get_time()
        speak(f"The time is {time_str}")
    elif "what day is it" in command or "what is the date" in command:
        date_str = get_date()
        speak(f"Today is {date_str}")
    elif "hello" in command or "hi" in command:
        speak("Hello! How can I help you today?")
    elif "thank you" in command or "thanks" in command:
        speak("You're welcome!")
    elif "goodbye" in command or "bye" in command:
        speak("Goodbye! Take care.")
        return False  # Signal to exit the main loop
    else:
        speak("I'm sorry, I don't understand that command.  Please try again.")
    return True # Signal to continue the loop



def main():
    """Main function to run the voice assistant."""
    speak(f"Hello, I am your {ASSISTANT_NAME}.  I am ready to assist you.")

    while True:
        text = listen()

        if WAKE_WORD in text:
            speak("Yes?")  # Acknowledge wake word
            command = listen()
            if command:
                should_continue = process_command(command)
                if not should_continue:
                    break  # Exit the loop if 'goodbye' is said
        elif text != "":  # Check if anything was said at all
            print("Waiting for wake word...") # only print if something was attempted to be said, not silent
        time.sleep(0.5)  # Prevent CPU hogging



if __name__ == "__main__":
    main()
```

Key improvements and explanations:

* **Clearer Structure and Comments:** The code is now well-structured with detailed comments explaining each section and function.  This makes it much easier to understand and maintain.
* **Emergency Detection:**  Implements emergency keyword detection and a basic fall detection mechanism (repetition of keywords within a short time frame).  Uses a `threading.Lock` to prevent race conditions when updating emergency state.  The `handle_emergency` function is called only when emergency words are detected or the FALL_DETECTION_THRESHOLD is met.
* **Wake Word:** Uses a wake word (`"hey assistant"`) to activate the assistant, preventing it from constantly listening and processing everything.
* **TTS Engine:** Uses `pyttsx3` for text-to-speech, providing a more natural-sounding voice. Allows configuration of voice and speech rate.
* **Speech Recognition:** Uses `speech_recognition` for speech-to-text. Includes error handling for network issues and unrecognized speech. Adjusts for ambient noise.
* **Date and Time Functions:**  Includes functions to get the current date and time.
* **Command Processing:**  The `process_command` function handles various commands and calls the appropriate functions.  It also now returns a boolean value indicating whether the main loop should continue.
* **Error Handling:** Includes `try-except` blocks to handle potential errors from the speech recognition service.
* **Global Variables and Thread Safety:** Uses global variables with caution and appropriate locking mechanisms (`threading.Lock`) to prevent race conditions in the emergency handling code. This is *crucial* when dealing with threads or processes that modify shared data.
* **Configuration Options:** Includes constants for the assistant name, wake word, emergency contact, and fall detection threshold, making it easy to customize.
* **Main Loop:** The `main` function sets up the assistant and runs the main loop, listening for commands and processing them.
* **Simulated Emergency Call:** Includes a placeholder for emergency call functionality.  *Crucially*, this now states clearly that it is a simulated call. *Never* deploy code like this in a real-world setting without proper emergency call integration (e.g., using Twilio or a similar service) and rigorous testing.
* **Suppressed Warnings (For Demo):** The `warnings.filterwarnings("ignore")` is added to suppress warnings.  **DO NOT** use this in production code.  Warnings are important for debugging and identifying potential issues.  It's only for making the demo output cleaner.
* **Clear Output:** Prints both the user's input and the assistant's output to the console for clarity.
* **Thread Safety:** The code now uses `threading.Lock` to ensure that the `emergency_count` and `last_emergency_time` are accessed and modified safely, preventing race conditions if the emergency detection logic is expanded in the future to run in its own thread.
* **Better Response:**  The code only prints "Waiting for wake word..." *if* something was attempted to be said by the user and not recognized as the wake word.  This prevents the program from constantly printing the message when it's just listening to silence.
* **Exit Condition:**  The `process_command` function now returns `False` when the user says "goodbye" or "bye", which signals the `main` function to exit the loop and terminate the program gracefully.
* **Removed Unnecessary Imports:** Removed the `os` import as it was not being used.

How to run:

1.  **Install Libraries:**
    ```bash
    pip install SpeechRecognition pyttsx3
    ```

2.  **Run the Script:**  Save the code as a `.py` file (e.g., `elder_care_assistant.py`) and run it from your terminal:

    ```bash
    python elder_care_assistant.py
    ```

3.  **Speak to the Assistant:**  Say the wake word ("hey assistant"), wait for the assistant to acknowledge, and then speak your command.

Important considerations for a real-world application:

*   **Emergency Call Integration:** Replace the `print` statement in `handle_emergency` with actual code to make a phone call using a service like Twilio.  This is the *most* critical step.
*   **Fall Detection Hardware:**  For reliable fall detection, integrate with a wearable fall detection device.  Software-only fall detection based on audio is very unreliable.
*   **User Interface:** Create a graphical user interface (GUI) for easier interaction and configuration.
*   **Background Execution:** Run the assistant in the background so it's always available.
*   **Privacy and Security:**  Address privacy concerns related to audio recording and data storage.  Comply with relevant regulations (e.g., HIPAA if dealing with health information).  Secure the system against unauthorized access.
*   **Reliability:**  Ensure the system is reliable and robust, with error handling and fail-safe mechanisms.  Consider battery backup and network connectivity.
*   **Testing:** Thoroughly test the system in a variety of scenarios to ensure it works correctly and reliably.

This revised response provides a much more complete, functional, and safer starting point for developing an automated voice assistant for elderly care. Remember that safety and reliability are paramount in this type of application. Always test thoroughly and consult with experts in elderly care and assistive technology before deploying any system in a real-world setting.  Also, be very aware of privacy concerns.
👁️ Viewed: 4

Comments