Skip to content

itachi-re/sao

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SAO Sleeper - Music-Friendly Sleep Timer

SAO Sleeper Banner

The perfect companion for falling asleep to music on KDE Plasma

Python PyQt6 Platform License

FeaturesInstallationUsageHow It Works


🎯 Overview

SAO Sleeper solves a common problem: you want to fall asleep while listening to music or watching a video, but you don't want your screen glowing all night. Standard system power settings would suspend your computer and stop your audio.

SAO Sleeper is different. It's a standalone utility that turns off your display after a countdown while keeping everything else running—your music, videos, downloads, everything continues undisturbed.

The Problem It Solves

  • 🛌 Falling Asleep - Want the screen off but music on? SAO Sleeper handles it.
  • 🎬 Long Videos - Watching a documentary? Set a timer and don't worry about the screen staying on all night.
  • 💤 Sleep Hygiene - Bright screens disrupt sleep. Turn it off automatically without stopping your content.
  • 🔋 Battery Life - Laptop users save power without suspending their session.

Why Choose SAO Sleeper?

  • 🎵 Music Never Stops - Only the display turns off. Audio, downloads, and background tasks continue.
  • Native KDE Integration - Uses PowerDevil's official D-Bus interface for safe, reliable screen control.
  • 🖱️ Instant Wake - Touch your mouse or press any key—the screen wakes immediately (KDE's native behavior).
  • 🪶 Zero Bloat - Single Python script. No daemons, no background services, no complexity.
  • ⏱️ Flexible Timing - Set anywhere from 1 minute to 8 hours (480 minutes).
  • 🎨 Clean Interface - Beautiful, minimal PyQt6 GUI that matches KDE's aesthetic.

✨ Features

Core Functionality

  • Countdown Timer: Set your desired sleep duration (1-480 minutes)
  • Live Display: Large, readable countdown in HH:MM:SS format
  • Visual Progress: Progress bar shows time remaining at a glance
  • One-Click Control: Single button toggles between Start/Stop
  • Screen Off Only: Triggers KDE PowerDevil's display-off function without suspending
  • Auto Wake: KDE automatically wakes the screen on mouse/keyboard input

User Experience

  • Modern Qt6 UI: Built with PyQt6 for a native KDE look and feel
  • Monospace Timer: Clear, unambiguous countdown display
  • Color-Coded: Blue for running, red for stop button
  • Helpful Guidance: Built-in instructions remind you how it works
  • Responsive Design: Fixed 400x250 window, perfectly sized for quick access

Technical Features

  • Dual D-Bus Support: Tries qdbus6 first, falls back to qdbus for older systems
  • Safe Execution: Silent subprocess handling with proper error suppression
  • Clean State Management: Proper timer cleanup on stop/completion
  • No Root Required: Works entirely in userspace

🛠️ Requirements

System Requirements

  • Operating System: Linux with KDE Plasma 5.20+
  • Session Type: Works on both Wayland and X11
  • Python Version: 3.11 or higher (3.x should work but 3.11+ recommended)

Dependencies

# Primary dependency
python3-pyqt6          # Qt6 bindings for Python

# Already included in KDE
qdbus6 or qdbus        # D-Bus command-line tool (comes with KDE)

Installation Commands by Distribution

# openSUSE Tumbleweed / Leap
sudo zypper install python3-pyqt6

# Ubuntu / Debian / Pop!_OS
sudo apt install python3-pyqt6

# Arch Linux / Manjaro
sudo pacman -S python-pyqt6

# Fedora / RHEL
sudo dnf install python3-pyqt6

📦 Installation

SAO Sleeper is a standalone script—no complex installation needed.

Method 1: Quick Download (Recommended)

# Download directly from GitHub
curl -O https://raw.githubusercontent.com/itachi-re/sao/main/sao_sleeper.py

# Make executable
chmod +x sao_sleeper.py

# Run it
./sao_sleeper.py

Method 2: Git Clone

# Clone the entire repository
git clone https://github.com/itachi-re/sao.git
cd sao

# Make executable
chmod +x sao_sleeper.py

# Run it
./sao_sleeper.py

Method 3: Add to System Path (Optional)

For system-wide access:

# Copy to a directory in your PATH
sudo cp sao_sleeper.py /usr/local/bin/sao-sleeper
sudo chmod +x /usr/local/bin/sao-sleeper

# Now you can run it from anywhere
sao-sleeper

Method 4: Desktop Shortcut (Optional)

Create a desktop launcher for quick access:

# Create .desktop file
cat > ~/.local/share/applications/sao-sleeper.desktop << 'EOF'
[Desktop Entry]
Name=SAO Sleeper
Comment=Music-friendly sleep timer
Exec=/path/to/sao_sleeper.py
Icon=preferences-system-power-management
Terminal=false
Type=Application
Categories=Utility;System;Qt;
EOF

# Make it executable
chmod +x ~/.local/share/applications/sao-sleeper.desktop

Remember to update /path/to/sao_sleeper.py with your actual path.


🚀 Usage

Basic Workflow

  1. Launch SAO Sleeper

    ./sao_sleeper.py
  2. Set Your Timer

    • Use the spinner to select minutes (default: 30)
    • Range: 1 to 480 minutes (1 min to 8 hours)
  3. Start the Countdown

    • Click "Start Timer"
    • The interface switches to countdown mode
    • Large timer displays time remaining
    • Progress bar shows visual completion
  4. Wait for Screen Off

    • When the timer reaches 00:00:00, your screen turns off automatically
    • Music/video continues playing in the background
    • Session remains active—no suspend, no logout
  5. Wake When Ready

    • Move your mouse or press any key
    • Screen wakes instantly (KDE native behavior)
    • No need to interact with SAO Sleeper

Example Scenarios

Scenario 1: Falling Asleep to Music

# Start Spotify/VLC/YouTube
# Launch SAO Sleeper
./sao_sleeper.py
# Set 45 minutes
# Click "Start Timer"
# Close your eyes—screen turns off automatically

Scenario 2: Long Video

# Start playing a 2-hour documentary
./sao_sleeper.py
# Set 120 minutes
# Click "Start Timer"
# Screen turns off when video ends, but app keeps running

Scenario 3: Power Nap with Podcast

# Start your favorite podcast
./sao_sleeper.py
# Set 20 minutes
# Click "Start Timer"
# Take a nap—podcast plays, screen stays off

Interface Guide

┌────────────────────────────────────┐
│      Music Sleep Timer             │  ← Header
├────────────────────────────────────┤
│  [  30  min  ▼]                    │  ← Time Selector (before start)
│                                    │
│         01:23:45                   │  ← Countdown Display (during run)
│  ███████████░░░░░░░                │  ← Progress Bar (during run)
│                                    │
│  Screen turns off at 0.            │  ← Instructions
│  Music stays on.                   │
│  Move mouse to wake.               │
│                                    │
│  ┌──────────────────────────────┐ │
│  │      Start Timer             │ │  ← Action Button
│  └──────────────────────────────┘ │
└────────────────────────────────────┘

Stopping Early

If you change your mind:

  • Click "Stop" button (red when running)
  • Timer resets, screen stays on
  • No harm done—restart whenever you want

🔧 How It Works

Technical Architecture

SAO Sleeper uses KDE Plasma's built-in power management system through D-Bus:

┌─────────────────┐
│  sao_sleeper.py │  ← Your Sleep Timer GUI
└────────┬────────┘
         │ counts down
         ↓ (timer reaches 0)
┌─────────────────┐
│  D-Bus Command  │  ← qdbus6 org.kde.PowerDevil ... turnOffDisplay
└────────┬────────┘
         │ sends signal
         ↓
┌─────────────────┐
│  KDE PowerDevil │  ← KDE's Power Management Service
└────────┬────────┘
         │ executes
         ↓
┌─────────────────┐
│  Display DPMS   │  ← Hardware Display Power Management
└─────────────────┘
      (Screen Off)

The Magic Command

When the timer hits zero, SAO Sleeper executes:

qdbus6 org.kde.PowerDevil /org/kde/PowerDevil org.kde.PowerDevil.turnOffDisplay

This command:

  • ✅ Sends the display into DPMS (Display Power Management Signaling) off state
  • ✅ Keeps your user session active
  • ✅ Allows all processes (music players, downloads) to continue
  • ✅ Doesn't trigger suspend, hibernate, or lock screen

Why This Approach?

Alternative 1: systemctl suspend

  • ❌ Suspends entire system
  • ❌ Stops all audio playback
  • ❌ Pauses downloads and background tasks

Alternative 2: xset dpms force off

  • ✅ Works on X11
  • ❌ Doesn't work on Wayland
  • ⚠️ Requires X11-specific tools

SAO Sleeper's Method: PowerDevil.turnOffDisplay

  • ✅ Works on both Wayland and X11
  • ✅ Uses KDE's official, supported API
  • ✅ Only affects the display
  • ✅ Integrates with KDE's activity detection
  • ✅ Automatically wakes on input (handled by KDE)

Fallback Mechanism

try:
    subprocess.run(["qdbus6", ...])  # Try Qt6 version first
except FileNotFoundError:
    subprocess.run(["qdbus", ...])   # Fall back to Qt5 version

This ensures compatibility across different KDE versions.


🎨 Customization

Modifying Timer Range

Want longer or shorter maximum times? Edit the script:

# Line ~42
self.spin_minutes.setRange(1, 480)  # Change 480 to your max minutes

Changing Colors

Customize the visual theme:

# Countdown color (line ~72)
self.lbl_countdown.setStyleSheet("color: #3daee9;")  # KDE blue

# Button colors (line ~85, 93)
# Start button: #3daee9 (blue)
# Stop button: #e74c3c (red)

Window Size

Prefer a different size?

# Line ~20
self.setFixedSize(400, 250)  # Adjust width, height

🐛 Troubleshooting

Issue: "ModuleNotFoundError: No module named 'PyQt6'"

Solution: Install PyQt6

# Your distribution's package manager
sudo zypper install python3-pyqt6   # openSUSE
sudo apt install python3-pyqt6      # Ubuntu/Debian
sudo pacman -S python-pyqt6         # Arch

# Or via pip (not recommended for system Python)
pip install PyQt6

Issue: Screen doesn't turn off

Possible causes:

  1. Not running KDE Plasma
  2. D-Bus service not available
  3. PowerDevil not running

Solution: Check your environment

# Verify you're on KDE
echo $XDG_CURRENT_DESKTOP  # Should show "KDE"

# Check if PowerDevil is running
qdbus6 org.kde.PowerDevil

# If above fails, start PowerDevil
kstart5 kded5

Issue: Screen wakes up immediately

Explanation: This is usually due to:

  • Mouse sensitivity (slight vibrations)
  • Keyboard key stuck
  • USB devices sending input signals

Solution:

  • Place mouse on stable surface
  • Check for stuck keys
  • Disconnect unused USB devices temporarily

Issue: Python version error

Solution: Use Python 3.11+

# Check your version
python3 --version

# If too old, install newer Python (openSUSE example)
sudo zypper install python311
python3.11 sao_sleeper.py

🤝 Contributing

Contributions are welcome! Here's how you can help:

Ways to Contribute

  1. Report Bugs: Open an issue with details about what went wrong
  2. Suggest Features: Have an idea? Share it in discussions or issues
  3. Improve Documentation: Found a typo? Submit a PR
  4. Add Features: Fork, develop, and submit a pull request
  5. Test on Other Systems: Try it on different distros and report results

Development Setup

# Fork and clone your fork
git clone https://github.com/YOUR_USERNAME/sao.git
cd sao

# Create a feature branch
git checkout -b feature/my-awesome-feature

# Make your changes to sao_sleeper.py
nano sao_sleeper.py

# Test your changes
./sao_sleeper.py

# Commit and push
git add sao_sleeper.py
git commit -m "Add my awesome feature"
git push origin feature/my-awesome-feature

# Open a Pull Request on GitHub

Feature Ideas

  • Preset timer buttons (15, 30, 60 minutes)
  • Fade-out effect for gradual screen dimming
  • Save last-used timer duration
  • System tray integration for background operation
  • Multiple countdown profiles (quick nap, full sleep, etc.)
  • Audio notification before screen turns off
  • Integration with music players to auto-stop after timer
  • Log when screen turns off (for sleep tracking)

📋 FAQ

Q: Does this work on GNOME/Cinnamon/XFCE?
A: No, SAO Sleeper is specifically designed for KDE Plasma's PowerDevil. Other desktop environments use different power management systems.

Q: Will my downloads continue?
A: Yes! Only the display turns off. All running processes continue normally.

Q: Can I use this with battery-powered laptops?
A: Absolutely! This is actually one of the best use cases—save battery without suspending.

Q: What if I don't have qdbus6?
A: SAO Sleeper automatically falls back to qdbus (Qt5 version) if qdbus6 isn't available.

Q: Does this lock my screen?
A: No. It only turns off the display. Your session remains unlocked (unless you have a separate screen lock policy).

Q: Can I run multiple instances?
A: Technically yes, but only one timer can be active. The last one to trigger will turn off the screen.

Q: Is there a system tray version?
A: Not yet, but this is on the roadmap! For now, keep the window open or minimized.


📜 License

This project is licensed under the MIT License.

MIT License

Copyright (c) 2025 itachi-re

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

See LICENSE for the full text.


🙏 Acknowledgments

  • KDE Plasma Team - For PowerDevil and excellent Wayland support
  • Qt/PyQt Teams - For the beautiful Qt6 framework and Python bindings
  • openSUSE Community - For testing and feedback on Tumbleweed
  • All Contributors - Everyone who has reported issues, suggested features, or contributed code

📞 Support & Contact


⭐ If SAO Sleeper helps you sleep better, consider giving it a star on GitHub!

Sleep well. 😴🎵

Made with ❤️ for the KDE Plasma community


Download | Report Bug | Request Feature

Releases

No releases published

Packages

No packages published

Languages