DEV Community

Cover image for Building an Interactive Badge Scanner System with Python Text-to-Speech
Ijeoma M. Jahsway
Ijeoma M. Jahsway

Posted on • Originally published at kumotechs.com

Building an Interactive Badge Scanner System with Python Text-to-Speech

In this tutorial, we'll create a badge scanner system that provides audio feedback using Python's text-to-speech capabilities. This project is perfect for intermediate Python developers who want to build a practical access control system with voice notifications.

Prerequisites

  • Python 3.x
  • Basic understanding of Python functions and data structures
  • Familiarity with pip package management

Required Packages

pip install pyttsx3
pip install keyboard
Enter fullscreen mode Exit fullscreen mode

Part 1: Setting Up Text-to-Speech Notifications

Let's start by creating our voice feedback system. We'll use pyttsx3 to generate clear audio notifications for different scanner events.

import pyttsx3

class VoiceNotifier:
    def __init__(self):
        self.engine = pyttsx3.init()

    def speak(self, message):
        self.engine.say(message)
        self.engine.runAndWait()

    def access_granted(self):
        self.speak("Access granted")

    def exit_granted(self):
        self.speak("Exit granted")

    def access_denied(self):
        self.speak("Access denied")

    def badge_exists(self):
        self.speak("Badge code already exists")

    def badge_added(self):
        self.speak("Badge code added")
Enter fullscreen mode Exit fullscreen mode

The VoiceNotifier class encapsulates all our text-to-speech functionality. By initializing the engine once in the constructor, we improve performance compared to creating a new engine for each notification.

Part 2: Badge Management System

Now, let's create our badge management system that will handle badge validation and tracking:

class BadgeManager:
    def __init__(self):
        self.voice = VoiceNotifier()
        self.valid_badges = set(range(100000))  # Valid badges from 00000-99999
        self.active_badges = set(['00000'])  # Currently active badges

    def validate_badge(self, badge_code):
        try:
            badge_int = int(badge_code)
            return 0 <= badge_int <= 99999
        except ValueError:
            return False

    def scan_badge(self, badge_code):
        """Process a badge scan for entry/exit"""
        if not self.validate_badge(badge_code):
            self.voice.access_denied()
            return False

        badge_code = int(badge_code)

        if badge_code not in self.valid_badges:
            self.voice.access_denied()
            return False

        if badge_code in self.active_badges:
            self.active_badges.remove(badge_code)
            self.voice.exit_granted()
        else:
            self.active_badges.add(badge_code)
            self.voice.access_granted()

        return True

    def add_badge(self, badge_code):
        """Add a new badge to the system"""
        if not self.validate_badge(badge_code):
            print("Invalid badge code format")
            return False

        badge_code = int(badge_code)

        if badge_code in self.valid_badges:
            self.voice.badge_exists()
            return False

        self.valid_badges.add(badge_code)
        self.voice.badge_added()
        return True

    def get_active_badges(self):
        return sorted(list(self.active_badges))
Enter fullscreen mode Exit fullscreen mode

Part 3: Creating the Interactive Interface

Finally, let's tie everything together with a keyboard-controlled interface:

import keyboard

class BadgeScanner:
    def __init__(self):
        self.badge_manager = BadgeManager()
        self.running = True

    def start(self):
        print("Badge Scanner System")
        print("-------------------")
        print("Press 's' to enter scan mode")
        print("Press 'a' to enter add badge mode")
        print("Press 'ESC' to exit")

        keyboard.on_press_key("s", lambda _: self.scan_mode())
        keyboard.on_press_key("a", lambda _: self.add_mode())
        keyboard.wait("esc")

    def scan_mode(self):
        print("\nScan Mode - Enter badge number or 'q' to quit")
        while True:
            badge = input("Scan badge: ")
            if badge.lower() == 'q':
                break
            self.badge_manager.scan_badge(badge)
            print(f"Active badges: {self.badge_manager.get_active_badges()}")

    def add_mode(self):
        print("\nAdd Badge Mode - Enter badge number or 'q' to quit")
        while True:
            badge = input("New badge code: ")
            if badge.lower() == 'q':
                break
            self.badge_manager.add_badge(badge)

# Run the system
if __name__ == "__main__":
    scanner = BadgeScanner()
    scanner.start()
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. Voice Notification System: The VoiceNotifier class provides clear audio feedback for all system events. It uses a single text-to-speech engine instance for better performance.

  2. Badge Management: The BadgeManager class handles all badge-related operations:

    • Maintains sets of valid and active badges
    • Validates badge numbers
    • Processes badge scans for entry/exit
    • Manages adding new badges
  3. User Interface: The BadgeScanner class creates an interactive interface:

    • Keyboard shortcuts for different modes
    • Clean input handling
    • Clear feedback for all operations

Key Features

  • Audio Feedback: Clear voice notifications for all actions
  • Dual-Purpose Scanning: Same badge scan handles both entry and exit
  • Valid Badge Range: Supports badge numbers from 00000 to 99999
  • Error Handling: Robust input validation and error messaging
  • Active Badge Tracking: Maintains list of currently active badges
  • Interactive Modes: Separate modes for scanning and adding badges

Usage Example

  1. Start the system:
scanner = BadgeScanner()
scanner.start()
Enter fullscreen mode Exit fullscreen mode
  1. Press 's' to enter scan mode:

    • Enter a badge number (e.g., "12345")
    • System will announce "Access granted"
    • Enter same number to exit, system announces "Exit granted"
  2. Press 'a' to enter add badge mode:

    • Enter a new badge number
    • System confirms addition with voice notification
  3. Press 'ESC' to exit the program

Improvements and Extensions

Here are some ways you could extend this system:

  • Add database integration for persistent storage
  • Implement time-based access restrictions
  • Add logging functionality
  • Create a GUI interface
  • Add support for physical badge scanners
  • Implement user roles and permissions

Conclusion

This badge scanner system demonstrates how to combine text-to-speech, input handling, and state management in Python. The modular design makes it easy to extend and modify for specific needs. The audio feedback makes it practical for real-world use where visual confirmation isn't always possible.

Top comments (0)