Stop Kodi on idle, start on WoL

Hi,

I just wanted to share this solution that is working for me to stop Kodi on OSMC when it has been idle for about two hours (by checking the screensaver) , and then to start it over when OSMC receives a wake-on-lan package. I’m using the Yatse android client and wake-on-lan is already integrated in the app.

This may be useful in case your Kodi power/cpu consumption is high.

Sorry for not posting to github. Comments are welcome.

/etc/systemd/system/wol-listener.service

[Unit]
Description=WoL Listener for Custom Actions
After=network.target

[Service]
ExecStart=/usr/bin/python3 /usr/local/bin/wol_listener.py
Restart=always
RestartSec=5
User=root

[Install]
WantedBy=multi-user.target

/usr/local/bin/wol_listener.py

#!/usr/bin/env python3
import socket
import struct
import subprocess

WOLPORT=5600
# Your Raspberry Pi's MAC address (e.g., "AA:BB:CC:DD:EE:FF")
MAC_ADDRESS="DC:A6:32:D6:E5:43" # ethernet mac

MAC = MAC_ADDRESS.replace(':', '').lower()
MAC_BYTES = bytes.fromhex(MAC)  # Convert MAC to bytes

# WoL magic packet is 6x FF + 16x MAC address
MAGIC_PACKET = b'\xff' * 6 + MAC_BYTES * 16

# Create a UDP socket to listen on port 9 (WoL default)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', WOLPORT))  # Listen on all interfaces

print("Listening for WoL packets...")

while True:
    data, addr = sock.recvfrom(1024)
    if MAGIC_PACKET in data:
        print(f"WoL packet received from {addr[0]}")
        # Run your custom action here (e.g., start a service, run a script)
        subprocess.run(["/usr/local/bin/wol_do.sh"])

/usr/local/bin/wol_do.sh

#!/bin/bash

set -Eeuo pipefail

echo "Starting Systemd MediaCenter Service"
systemctl start mediacenter

/etc/systemd/system/kodi-idle-check.service

[Unit]
Description=Check Kodi Screensaver State

[Service]
Type=oneshot
ExecStart=/usr/local/bin/check_kodi_idle.sh
User=osmc

/etc/systemd/system/kodi-idle-check.timer

[Unit]
Description=Run Kodi Screensaver Check Every 5 Minutes

[Timer]
OnUnitActiveSec=5m
OnBootSec=5m

[Install]
WantedBy=timers.target

/usr/local/bin/check_kodi_idle.sh

#!/bin/bash

# Kodi API credentials
KODI_USER="osmc"
KODI_PASS="osmc"
KODI_HOST="localhost:80"

# Screensaver check settings
MAX_CHECKS=24          # Number of checks (24 × 5min = 2h)
CHECK_INTERVAL=300     # not used, implemented as systemd service
LOCK_FILE="/tmp/kodi_idle_check.lock"

# Ensure only one instance runs
if [ -f "$LOCK_FILE" ]; then
    exit 0
else
    touch "$LOCK_FILE"
fi

# Initialize counter
if [ ! -f "/tmp/kodi_screensaver_count" ]; then
    echo "0" > "/tmp/kodi_screensaver_count"
fi
COUNTER=$(cat "/tmp/kodi_screensaver_count")

# Check if screensaver is active
RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"XBMC.GetInfoBooleans","params":{"booleans":["System.ScreenSaverActive"]},"id":1}' "http://$KODI_USER:$KODI_PASS@$KODI_HOST/jsonrpc")
SCREENSAVER_ACTIVE=$(echo "$RESPONSE" | jq -r '.result["System.ScreenSaverActive"]')

if [ "$SCREENSAVER_ACTIVE" = "true" ]; then
    # Increment counter
    COUNTER=$((COUNTER + 1))
    echo "$COUNTER" > "/tmp/kodi_screensaver_count"

    # If screensaver active for 2h (24 checks), stop mediacenter
    if [ "$COUNTER" -ge "$MAX_CHECKS" ]; then
        echo "0" > "/tmp/kodi_screensaver_count"  # Reset counter
        sudo systemctl stop mediacenter
    fi
else
    # Reset counter if screensaver is inactive
    echo "0" > "/tmp/kodi_screensaver_count"
fi

# Cleanup
rm -f "$LOCK_FILE"

Smart. Our hardware can support WoL from shutdown. But the software is not there presently.

I’ll take a look at implementation in bootloader and kernel when we update the kernel as I think most of the work there is done. This would let you drop Vero V to a very low power state.

Sam