Disclaimer: This article is for educational purposes only. Don't break the law, be nice to your kids, and don't forget that you're responsible for what you do with your own devices. Disclaimer: This article is for educational purposes only. Don't break the law, be nice to your kids, and don't forget that you're responsible for what you do with your own devices. Disclaimer: This article is for educational purposes only. Don't break the law, be nice to your kids, and don't forget that you're responsible for what you do with your own devices. The Problem No One Talks About The Digital Sleep Paradox In an era where screens dominate bedtime routines, millions now fall asleep to YouTube videos, podcasts, or streaming apps. However, this habit has a hidden cost: uncontrolled volume exposure, especially for children. As a parent and developer, I faced this problem firsthand—my child’s late-night YouTube binges led to restless sleep and morning irritability. Free apps in the Google Play Store, like Volume Limiter, Volume Control were a failure: they crashed, had no settings, or were too intrusive. Perhaps commercial apps would be better, but I haven't tested this since they cost money, often quite a bit. Volume Limiter Volume Control The Hack (Totally Illegal…ish) I built a script that connects to your Android device wirelessly and keeps an eye on its volume. If it gets too loud — it gently lowers it. No stopping videos, no screen flashing, no user interaction. Just quiet magic. Yes, technically, it uses ADB (Android Debug Bridge) over Wi-Fi, which is a developer tool and not meant for bedtime parenting. But that’s the beauty of it. Setting Up Your Development Environment Setting up a development environment and connectivity is crucial before diving into the code. This will ensure you have all the necessary tools and libraries, streamlining the development process. I use macOS, so all examples in the story will be with this system, but using Windows does not make the process much more difficult compared to MacOS. The only difference is that in the MacOS operating system, Python is already installed, and in Windows, you will have to install Python yourself from here: Windows Python Windows Python Here's a more detailed breakdown: Download and Extract Platform Tools: Go to the official Android Developers website: Navigate to Android SDK Platform-Tools. Download the SDK Platform Tools: Download the latest version for your operating system (Windows, macOS, or Linux). Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows). C:\adb Add Platform Tools to your System's PATH: Windows: Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu). Click "Edit the system environment variables". Click "Environment Variables". In the "System variables" section, find the "Path" variable, select it, and click "Edit". Click "New" and add the path to the platform-tools directory (e.g., C:\adb). macOS/Linux: Open your terminal. Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. Verify ADB Installation: Open a command line interface (CLI): Using the Windows Search Bar (Windows OS): Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Using Spotlight Search (macOS): Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Type adb and press Enter. adb If adb is installed correctly, you should see the ADB help message. Enable USB Debugging on your Android Device: Go to "Settings" on your Android device. Scroll down and select "About Phone". Find "Build Number" and tap it 7 or more times to unlock Developer Options. Go back to the main "Settings" page, and now you'll see "Developer Options". Select "Developer Options". Scroll down to "USB Debugging" and toggle it on. Download and Extract Platform Tools: Go to the official Android Developers website: Navigate to Android SDK Platform-Tools. Download the SDK Platform Tools: Download the latest version for your operating system (Windows, macOS, or Linux). Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows). C:\adb Download and Extract Platform Tools: Go to the official Android Developers website: Navigate to Android SDK Platform-Tools. Download the SDK Platform Tools: Download the latest version for your operating system (Windows, macOS, or Linux). Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows). Go to the official Android Developers website: Navigate to Android SDK Platform-Tools. Go to the official Android Developers website: Navigate to Android SDK Platform-Tools. Navigate to Android SDK Platform-Tools. Android SDK Platform-Tools Download the SDK Platform Tools: Download the latest version for your operating system (Windows, macOS, or Linux). Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows). Download the SDK Platform Tools: Download the latest version for your operating system (Windows, macOS, or Linux). Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows). Download the latest version for your operating system (Windows, macOS, or Linux). Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows). C:\adb C:\adb Add Platform Tools to your System's PATH: Windows: Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu). Click "Edit the system environment variables". Click "Environment Variables". In the "System variables" section, find the "Path" variable, select it, and click "Edit". Click "New" and add the path to the platform-tools directory (e.g., C:\adb). macOS/Linux: Open your terminal. Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. Add Platform Tools to your System's PATH: Windows: Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu). Click "Edit the system environment variables". Click "Environment Variables". In the "System variables" section, find the "Path" variable, select it, and click "Edit". Click "New" and add the path to the platform-tools directory (e.g., C:\adb). macOS/Linux: Open your terminal. Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. Windows: Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu). Click "Edit the system environment variables". Click "Environment Variables". In the "System variables" section, find the "Path" variable, select it, and click "Edit". Click "New" and add the path to the platform-tools directory (e.g., C:\adb). Windows: Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu). Click "Edit the system environment variables". Click "Environment Variables". In the "System variables" section, find the "Path" variable, select it, and click "Edit". Click "New" and add the path to the platform-tools directory (e.g., C:\adb). Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu). Click "Edit the system environment variables". Click "Environment Variables". In the "System variables" section, find the "Path" variable, select it, and click "Edit". Click "New" and add the path to the platform-tools directory (e.g., C:\adb). macOS/Linux: Open your terminal. Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. macOS/Linux: Open your terminal. Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. Open your terminal. Open your terminal. Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc). For example: export PATH=$PATH:/path/to/platform-tools. export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n" In my case, it’ll be something like this: Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. Restart your terminal or source the configuration file (e.g., source ~/.bashrc). From now on, we will work only in the command line. In my case, it will be the terminal. From now on, we will work only in the command line. In my case, it will be the terminal. Verify ADB Installation: Open a command line interface (CLI): Using the Windows Search Bar (Windows OS): Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Using Spotlight Search (macOS): Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Type adb and press Enter. adb If adb is installed correctly, you should see the ADB help message. Verify ADB Installation: Open a command line interface (CLI): Using the Windows Search Bar (Windows OS): Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Using Spotlight Search (macOS): Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Type adb and press Enter. adb If adb is installed correctly, you should see the ADB help message. Open a command line interface (CLI): Using the Windows Search Bar (Windows OS): Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Using Spotlight Search (macOS): Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Open a command line interface (CLI): Using the Windows Search Bar (Windows OS): Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Using Spotlight Search (macOS): Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Using the Windows Search Bar (Windows OS): Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Click the Start button or the magnifying glass icon in the taskbar. Type "cmd" (without quotes) in the search bar. Click on the "Command Prompt" result. To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator". Using Spotlight Search (macOS): Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Click the magnifying glass icon in the menu bar (or press Cmd+Space). Type "Terminal" and double-click it to open. Type adb and press Enter. adb Type adb and press Enter. adb adb If adb is installed correctly, you should see the ADB help message. If adb is installed correctly, you should see the ADB help message. Enable USB Debugging on your Android Device: Go to "Settings" on your Android device. Scroll down and select "About Phone". Find "Build Number" and tap it 7 or more times to unlock Developer Options. Go back to the main "Settings" page, and now you'll see "Developer Options". Select "Developer Options". Scroll down to "USB Debugging" and toggle it on. Enable USB Debugging on your Android Device: Go to "Settings" on your Android device. Scroll down and select "About Phone". Find "Build Number" and tap it 7 or more times to unlock Developer Options. Go back to the main "Settings" page, and now you'll see "Developer Options". Select "Developer Options". Scroll down to "USB Debugging" and toggle it on. Go to "Settings" on your Android device. Scroll down and select "About Phone". Find "Build Number" and tap it 7 or more times to unlock Developer Options. Go back to the main "Settings" page, and now you'll see "Developer Options". Select "Developer Options". Scroll down to "USB Debugging" and toggle it on. Setting Up Your Connection The next step will be connecting your mobile device with your PC. This is a relatively simple step that consists of two parts: Wire connection; Wireless connection. Wire connection; Wireless connection. Wire Connection: You should connect your mobile device to your PC using the cable (USB A/USB C or USB A/micro USB, etc.). After that, you open the terminal and type the following command: adb devices adb devices For now, we are ready to enable TCP/IP mode with the following command: adb tcpip 5555 adb tcpip 5555 If we are already in the terminal, then we can check the IP address of the mobile device in our Wi-Fi network without looking at the mobile device. Let's run the following command to find out the IP address that we will need later when establishing a wireless connection: adb -d shell "ip route | awk '/wlan0/ {print \$9}'" adb -d shell "ip route | awk '/wlan0/ {print \$9}'" Wireless Connection: Now that you have your device's IP address, it's time to connect wirelessly. No need for a wired connection anymore. Once you've run adb tcpip 5555, you can safely unplug the USB cable. The rest of the magic will happen over Wi-Fi. adb tcpip 5555 Make sure both your smartphone and computer are on the same Wi-Fi network. Then, in your terminal, type the following command: adb connect <DEVICE_IP>:5555 adb connect <DEVICE_IP>:5555 For example, if your device IP is 10.0.0.108, you’d enter: 10.0.0.108 adb connect 10.0.0.108:5555 adb connect 10.0.0.108:5555 If all goes well, you'll see a message like: Let’s Talk About the Problem Again Let’s take a step back and remember what we’re solving. Your child falls asleep peacefully watching a quiet video — maybe a bedtime story or some relaxing sounds. But two hours later? YouTube’s auto-play kicks in, a loud ad blares, or some high-energy cartoon soundtrack wakes them up. They’re groggy. You’re groggy. Everyone starts their day already drained. What we needed was a silent guardian — something invisible and reliable. A system that would gently lower the volume in the background without stopping playback, without flashing annoying pop-ups, and without waking the user. That’s exactly what this script does. Architecture at a Glance Here’s a quick diagram that shows how everything connects: Your computer (running the Python script) connects to the Android device via ADB over Wi-Fi, monitors the volume periodically, and reduces it if needed. Your computer (running the Python script) connects to the Android device via ADB over Wi-Fi, monitors the volume periodically, and reduces it if needed. The Script That Does the Magic The core of the solution is a Python script that communicates with your Android device via ADB over Wi-Fi. Every 30 seconds, it checks the current music stream volume. If the volume is above 5 (Android typically uses a 15-point scale), the script gently lowers it — one step at a time, with short pauses. If the volume is already 5 or lower, it just keeps watch — waiting silently in case the volume is raised again. The best part? It respects manual changes. If someone lowers the volume themselves, the script notices and doesn’t interfere. It’s quiet. It’s adaptive. It’s invisible — just like a good bedtime assistant should be. The Script’s Evolution: From Tiny Hack to Reliable Tool When I first wrote this script, it was barely a few lines long. It looked something like this: import subprocess import time import re def get_stream_volume(): cmd = "adb shell dumpsys audio | awk '/- STREAM_MUSIC:/{flag=1; count=0} flag && count<=5 {print; count++} /^$/{flag=0}'" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) match = re.search(r'streamVolume:(\d+)', result.stdout) return int(match.group(1)) if match else None def set_volume(level): cmd = f"adb shell cmd media_session volume --stream 3 --set {level}" subprocess.run(cmd, shell=True) print(f"Volume set to {level}") def monitor_volume(): while True: volume = get_stream_volume() if volume is None: print("Failed to get volume level. Retrying...") time.sleep(5) continue print(f"Current volume: {volume}") if volume == 15: for vol in range(14, 4, -1): set_volume(vol) time.sleep(30) while get_stream_volume() == 5: print("Volume is at 5, monitoring every 60 seconds...") time.sleep(60) if __name__ == "__main__": monitor_volume() os.system("adb shell dumpsys audio | grep -i 'streamVolume'") import subprocess import time import re def get_stream_volume(): cmd = "adb shell dumpsys audio | awk '/- STREAM_MUSIC:/{flag=1; count=0} flag && count<=5 {print; count++} /^$/{flag=0}'" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) match = re.search(r'streamVolume:(\d+)', result.stdout) return int(match.group(1)) if match else None def set_volume(level): cmd = f"adb shell cmd media_session volume --stream 3 --set {level}" subprocess.run(cmd, shell=True) print(f"Volume set to {level}") def monitor_volume(): while True: volume = get_stream_volume() if volume is None: print("Failed to get volume level. Retrying...") time.sleep(5) continue print(f"Current volume: {volume}") if volume == 15: for vol in range(14, 4, -1): set_volume(vol) time.sleep(30) while get_stream_volume() == 5: print("Volume is at 5, monitoring every 60 seconds...") time.sleep(60) if __name__ == "__main__": monitor_volume() os.system("adb shell dumpsys audio | grep -i 'streamVolume'") But soon, reality kicked in. What happens if the device disconnects in the middle of the night? What if ADB throws a timeout? What if the phone isn’t paired? What if the script crashes while everyone’s asleep? So, the script evolved. Sometimes, the device wasn’t connected. So I added adb connect ip:port. Sometimes ADB crashed mid-night. I added exception handling and retries. Logging? Yep, added that too. File logging and console logging? Of course. Volume changes mid-sleep? Now, the script tracks that too — and only intervenes when needed. Monitoring frequency? Different intervals for high vs. low volume levels. And yes, graceful shutdown Ctrl + C. Sometimes, the device wasn’t connected. So I added adb connect ip:port. Sometimes, the device wasn’t connected. adb connect ip:port Sometimes ADB crashed mid-night. I added exception handling and retries. Sometimes ADB crashed mid-night. Logging? Yep, added that too. Logging? File logging and console logging? Of course. File logging and console logging? Volume changes mid-sleep? Now, the script tracks that too — and only intervenes when needed. Volume changes mid-sleep? Monitoring frequency? Different intervals for high vs. low volume levels. Monitoring frequency? And yes, graceful shutdown Ctrl + C. And yes, Ctrl + C What started as a few lines of script turned into a tiny watchdog that babysits your phone — so you don’t have to. import subprocess import time import re import logging from datetime import datetime logging.basicConfig( filename='volume_control.log', level=logging.INFO, format='[%(asctime)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) ADB_DEVICE = "10.0.0.108:5555" def log(message): timestamp = get_timestamp() print(f'[{timestamp}] {message}') logging.info(message) def get_timestamp(): return datetime.now().strftime('%Y-%m-%d %H:%M:%S') def connect_adb(): subprocess.run(f"adb connect {ADB_DEVICE}", shell=True) log(f"Reconnected to ADB at {ADB_DEVICE}") def get_stream_volume(): cmd = "adb shell dumpsys audio | awk '/- STREAM_MUSIC:/{flag=1; count=0} flag && count<=5 {print; count++} /^$/{flag=0}'" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) match = re.search(r'streamVolume:(\d+)', result.stdout) return int(match.group(1)) if match else None def safe_get_stream_volume(retries=3, delay=5): for attempt in range(retries): volume = get_stream_volume() if volume is not None: return volume log(f"Attempt {attempt + 1}: Failed to get volume. Retrying after reconnect...") connect_adb() time.sleep(delay) log("All attempts failed. Giving up temporarily.") return None def set_volume(level): cmd = f"adb shell cmd media_session volume --stream 3 --set {level}" subprocess.run(cmd, shell=True) log(f"Volume set to {level}, waiting 30 seconds...") def monitor_volume(): while True: volume = safe_get_stream_volume() if volume is None: log("Initial volume read failed. Retrying in 30 seconds...") time.sleep(30) continue log(f"Current volume: {volume}") while volume > 5: set_volume(volume - 1) time.sleep(30) volume = safe_get_stream_volume() if volume is None: log("Failed to read volume during decreasing.") break while True: volume = safe_get_stream_volume() if volume is None: log("Failed to read volume during monitoring.") time.sleep(30) break if volume > 5: log(f"Volume increased to {volume}, restarting decreasing") break log(f"Volume is at {volume}, monitoring every 60 seconds...") time.sleep(60) if __name__ == "__main__": try: monitor_volume() except KeyboardInterrupt: log("Script stopped by user (Ctrl+C)") except Exception as e: log(f"Unexpected error: {e}") finally: log("Script exited.") import subprocess import time import re import logging from datetime import datetime logging.basicConfig( filename='volume_control.log', level=logging.INFO, format='[%(asctime)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) ADB_DEVICE = "10.0.0.108:5555" def log(message): timestamp = get_timestamp() print(f'[{timestamp}] {message}') logging.info(message) def get_timestamp(): return datetime.now().strftime('%Y-%m-%d %H:%M:%S') def connect_adb(): subprocess.run(f"adb connect {ADB_DEVICE}", shell=True) log(f"Reconnected to ADB at {ADB_DEVICE}") def get_stream_volume(): cmd = "adb shell dumpsys audio | awk '/- STREAM_MUSIC:/{flag=1; count=0} flag && count<=5 {print; count++} /^$/{flag=0}'" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) match = re.search(r'streamVolume:(\d+)', result.stdout) return int(match.group(1)) if match else None def safe_get_stream_volume(retries=3, delay=5): for attempt in range(retries): volume = get_stream_volume() if volume is not None: return volume log(f"Attempt {attempt + 1}: Failed to get volume. Retrying after reconnect...") connect_adb() time.sleep(delay) log("All attempts failed. Giving up temporarily.") return None def set_volume(level): cmd = f"adb shell cmd media_session volume --stream 3 --set {level}" subprocess.run(cmd, shell=True) log(f"Volume set to {level}, waiting 30 seconds...") def monitor_volume(): while True: volume = safe_get_stream_volume() if volume is None: log("Initial volume read failed. Retrying in 30 seconds...") time.sleep(30) continue log(f"Current volume: {volume}") while volume > 5: set_volume(volume - 1) time.sleep(30) volume = safe_get_stream_volume() if volume is None: log("Failed to read volume during decreasing.") break while True: volume = safe_get_stream_volume() if volume is None: log("Failed to read volume during monitoring.") time.sleep(30) break if volume > 5: log(f"Volume increased to {volume}, restarting decreasing") break log(f"Volume is at {volume}, monitoring every 60 seconds...") time.sleep(60) if __name__ == "__main__": try: monitor_volume() except KeyboardInterrupt: log("Script stopped by user (Ctrl+C)") except Exception as e: log(f"Unexpected error: {e}") finally: log("Script exited.") Today, the script is production-grade — and open source. But make sure to change this line ADB_DEVICE = "10.0.0.108:5555" in the script with your IP address from “Setting Up Your Connection”. “Setting Up Your Connection” Running the Script: Two Easy Options as Well as Cron You’ve got two main ways to run the script: Directly with Python Directly with Python If you have Python 3 installed, you can just run: python3 reduce_volume.py python3 reduce_volume.py It’ll start immediately and do its job quietly in the background. As a Standalone Executable As a Standalone Executable Want to share it with someone who doesn’t have Python installed? You can convert the script into a standalone .app for macOS or .exe for Windows, using PyInstaller: .app .exe PyInstaller pyinstaller --onefile reduce_volume.py pyinstaller --onefile reduce_volume.py This will create a portable app that can be launched with a double-click — no Python required. Even schedule it with a cron job or task scheduler if you're fancy. Even schedule it with a cron job or task scheduler if you're fancy. One More Thing: Remote ADB Limitations It’s important to note that ADB over Wi-Fi can be fragile. Your remote connection will break if: The phone reboots. The Wi-Fi network changes. Developer Mode or USB Debugging gets disabled. The device goes too long without ADB activity (some systems auto-kick inactive connections). And many others … The phone reboots. The Wi-Fi network changes. Developer Mode or USB Debugging gets disabled. The device goes too long without ADB activity (some systems auto-kick inactive connections). And many others … So if the script stops working, just repeat the steps from “Setting Up Your Connection”: “Setting Up Your Connection” Connect the mobile device with a wire to your personal computer. Run the command adb tcpip 5555 adb tcpip 5555 And run adb connect <DEVICE_IP>:5555 Connect the mobile device with a wire to your personal computer. Connect the mobile device with a wire to your personal computer. Run the command adb tcpip 5555 adb tcpip 5555 Run the command adb tcpip 5555 adb tcpip 5555 adb tcpip 5555 adb tcpip 5555 And run adb connect <DEVICE_IP>:5555 And run adb connect <DEVICE_IP>:5555 adb connect <DEVICE_IP>:5555 adb connect 10.0.0.108:5555 adb connect 10.0.0.108:5555 and you’ll be back in business. Final Thoughts This hack isn’t about silencing your kid’s fun. It’s about protecting their sleep — and your sanity — from unexpected tech surprises. This may be a small script, but for my family and me, it was life-changing. No more 2 AM YouTube wakeups. No more cranky mornings. Just peaceful nights and a subtle bit of parenting automation. Is it a bit of a hack? Sure. Does it work reliably? Absolutely. Is it legal? Technically yes, but it operates in a gray zone (ADB access and automated control are not officially supported by Google for end-users). But you know what? As long as it helps a tired parent (or even yourself) sleep better — it's worth it. It's subtle. It's invisible. And it works. Is it a bit of a hack? Sure. Does it work reliably? Absolutely. Is it legal? Technically yes, but it operates in a gray zone (ADB access and automated control are not officially supported by Google for end-users). But you know what? As long as it helps a tired parent (or even yourself) sleep better — it's worth it. It's subtle. It's invisible. And it works. Let me know if you want the source code, a one-click setup, or an improved version. And hey — sleep well. You’ve earned it. P.S. This solution can be improved and expanded - for example, set up a schedule, adapt to different profiles, track device activity, etc. But even in its basic form, it already solves the main problem: it helps you fall asleep - and sleep peacefully. And yes, if you have a specific request or idea, I will be happy to help you, and at the same time, this will be a topic for another article. P.S. This solution can be improved and expanded - for example, set up a schedule, adapt to different profiles, track device activity, etc. But even in its basic form, it already solves the main problem: it helps you fall asleep - and sleep peacefully. And yes, if you have a specific request or idea, I will be happy to help you, and at the same time, this will be a topic for another article.