Skip to content

white100s/macos-sleep-manager-python

Repository files navigation

Sunho Sleep Manager

macOS Python PyObjC License

Sunho Sleep Manager is a macOS menu bar app that sends Slack notifications when your laptop lid closes or opens, and lets you block/allow sleep with one click.


Features

  • Lid close / open → Slack notification (via Incoming Webhook)
  • Menu bar toggle — block or allow sleep instantly
    • SL (normal) — sleep allowed
    • SL + underline — sleep blocked (pmset disablesleep 1)
  • Remote HTTP API — control sleep state over Tailscale from any device
  • i18n — UI and default Slack messages automatically match your macOS language Supported: English · 한국어 · 日本語 · 简体中文 · 繁體中文 · Français · Deutsch · Español
  • Recent history — last 10 sleep/wake events shown in the menu
  • Runs at login via LaunchAgent

Requirements

  • macOS 12 Monterey or later
  • Python 3 (pre-installed on macOS)
  • PyObjC — Cocoa bridge for Python (installed automatically by setup.sh)

Installation

1. Clone the repository

git clone https://github.com/<your-username>/sleep-manager.git
cd sleep-manager

2. Create a Slack Incoming Webhook

Go to https://api.slack.com/apps → create an app → enable Incoming Webhooks → copy the URL.

3. Configure config.json

{
  "slack_webhook_url": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
  "include_computer_name": true,
  "computer_name": "",
  "language": "",
  "messages": {
    "sleep": "",
    "wake": ""
  },
  "api_port": 8765,
  "api_token": ""
}
Key Default Notes
slack_webhook_url (required) Slack Incoming Webhook URL
include_computer_name true Prepend hostname to messages
computer_name "" Empty = auto-detect via hostname
language "" Empty = auto-detect from macOS. Override with "en", "ko", "ja", "zh-Hans", "zh-Hant", "fr", "de", or "es"
messages.sleep / .wake "" Empty = use locale default. Supports {computer_name} placeholder
api_port 8765 HTTP API listen port
api_token "" Empty = no auth. Set to require X-Token: <token> header

4. Run the install script

bash setup.sh

The script will:

  • Install PyObjC if not already present
  • Register net.sunho.sleep-manager.plist under ~/Library/LaunchAgents/
  • Grant passwordless sudo pmset access via /etc/sudoers.d/sleep-manager (requires your admin password one time only)

Running Manually

python3 sleep_notifier.py

Verifying It Works

# Check the service is running
launchctl list | grep sleep-manager

# Follow live logs
tail -f ~/Library/Logs/sleep-manager.log

Service Management

PLIST=~/Library/LaunchAgents/net.sunho.sleep-manager.plist

# Stop
launchctl unload "$PLIST"

# Restart
launchctl unload "$PLIST" && launchctl load "$PLIST"

HTTP API

The API listens on 0.0.0.0:<api_port> — intended for use over a Tailscale internal network.

Endpoint Description
GET /status Returns {"disablesleep": 0|1}
GET /sleep?value=1 Block sleep (pmset disablesleep 1)
GET /sleep?value=0 Allow sleep (pmset disablesleep 0)

If api_token is set, all requests must include the header X-Token: <token>.

# Example: block sleep remotely
curl -H "X-Token: mytoken" http://<tailscale-ip>:8765/sleep?value=1

Language / i18n

The app detects your macOS language automatically. To pin a specific language, set "language" in config.json:

{ "language": "ja" }

Locale files live in locales/*.json. Each file contains UI strings and default Slack message templates. To customize Slack messages, set non-empty values in messages.sleep / messages.wake in config.json — these override the locale defaults.


File Structure

sleep-manager/
├── sleep_notifier.py                  # Main script (Python 3 + PyObjC)
├── config.json                        # Configuration
├── locales/
│   ├── en.json                        # English
│   ├── ko.json                        # Korean (한국어)
│   ├── ja.json                        # Japanese (日本語)
│   ├── zh-Hans.json                   # Simplified Chinese (简体中文)
│   ├── zh-Hant.json                   # Traditional Chinese (繁體中文)
│   ├── fr.json                        # French (Français)
│   ├── de.json                        # German (Deutsch)
│   └── es.json                        # Spanish (Español)
├── net.sunho.sleep-manager.plist      # LaunchAgent definition
└── setup.sh                           # Install script

Uninstall

launchctl unload ~/Library/LaunchAgents/net.sunho.sleep-manager.plist
rm ~/Library/LaunchAgents/net.sunho.sleep-manager.plist
sudo rm /etc/sudoers.d/sleep-manager

Notes

  • With pmset disablesleep 1 active, closing the lid keeps the CPU running — watch your battery.
  • Before quitting the app, use the menu bar to re-enable sleep if you had it blocked.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors