Skip to content

kernelkaribou/motion-standby

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Motion Standby Service

A Python service for Raspberry Pi CM5 that automatically controls HDMI display power based on motion detection using an LD2410C radar sensor. The display turns off after a configurable timeout period when no motion is detected, and turns back on immediately when motion is detected.

Features

  • Automatic Display Control: Uses Wayland wlopm for reliable display power management
  • Smart Motion Detection: Advanced filtering to prevent false positives from micro-movements
  • Configurable Sensitivity: Adjustable thresholds for different environments
  • Systemd Integration: Runs as a user service with automatic startup
  • Robust Operation: Built-in error handling and recovery mechanisms
  • Minimal Dependencies: Lightweight Python implementation

Hardware Requirements

  • Raspberry Pi CM5 with GPIO pins
  • LD2410C radar sensor
  • HDMI display connected to Pi

Sensor Wiring

Connect the LD2410C sensor to your Raspberry Pi:

LD2410C -> Raspberry Pi CM5
VCC     -> 5V (Pin 4)
GND     -> GND (Pin 6) 
TX      -> GPIO 14 (Pin 8)
RX      -> GPIO 15 (Pin 10)

Pin Layout:

 1  3.3V    5V   2
 3  GPIO2   5V   4
 5  GPIO3   GND  6
 7  GPIO4   TX  8  <- LD2410C TX to GPIO 14
 9  GND     RX  10 <- LD2410C RX to GPIO 15

Software Dependencies

  • Python 3.7+
  • lgpio - GPIO access library
  • wlopm - Wayland display power management

Quick Start

  1. Clone and Install:

    git clone <repository-url> motion-standby
    cd motion-standby
    ./install_service.sh
  2. Start the Service:

    systemctl --user start motion-standby
  3. Check Status:

    systemctl --user status motion-standby

Configuration

The service is configured via motion_config.json:

{
    "timeout_minutes": 30,
    "check_interval_seconds": 1,
    "sensor": {
        "rx_pin": 14,
        "tx_pin": 15
    },
    "log_level": "INFO",
    "detection_threshold": 5,
    "motion_duration_min": 3.0,
    "cooldown_period": 10.0,
    "debounce_time": 0.3
}

Configuration Parameters

Parameter Default Description
timeout_minutes 30 Minutes of inactivity before display turns off
check_interval_seconds 1 How often to check for motion (seconds)
sensor.rx_pin 14 GPIO pin for sensor RX (UART communication)
sensor.tx_pin 15 GPIO pin for sensor TX (UART communication)
log_level INFO Logging level (DEBUG, INFO, WARNING, ERROR)
detection_threshold 5 Consecutive positive readings required for motion
motion_duration_min 3.0 Minimum seconds of motion to trigger
cooldown_period 10.0 Seconds to wait between motion detections
debounce_time 0.3 Anti-jitter delay between sensor readings

Sensitivity Tuning

The LD2410C sensor is very sensitive and may detect micro-movements. The service includes multiple filtering mechanisms:

Understanding the Filters

  1. Detection Threshold (detection_threshold):

    • Number of consecutive positive readings needed
    • Higher = less sensitive, fewer false positives
    • Range: 3-10 (recommended: 5)
  2. Motion Duration (motion_duration_min):

    • Minimum time motion must persist
    • Filters out brief micro-movements
    • Range: 1.0-5.0 seconds (recommended: 3.0)
  3. Cooldown Period (cooldown_period):

    • Time to wait after detecting motion before detecting again
    • Prevents rapid re-triggering
    • Range: 5.0-30.0 seconds (recommended: 10.0)
  4. Debounce Time (debounce_time):

    • Anti-jitter delay between sensor readings
    • Smooths out electrical noise
    • Range: 0.1-1.0 seconds (recommended: 0.3)

Tuning Guidelines

For Quiet Environments (minimal movement):

{
    "detection_threshold": 3,
    "motion_duration_min": 2.0,
    "cooldown_period": 5.0
}

For Normal Environments (occasional movement):

{
    "detection_threshold": 5,
    "motion_duration_min": 3.0,
    "cooldown_period": 10.0
}

For Active Environments (frequent movement):

{
    "detection_threshold": 7,
    "motion_duration_min": 4.0,
    "cooldown_period": 15.0
}

For Noisy Environments (many false positives):

{
    "detection_threshold": 8,
    "motion_duration_min": 5.0,
    "cooldown_period": 20.0
}

Testing Your Settings

Use the test mode to validate your configuration:

# Test with debug logging and 1-minute timeout
python3 motion_standby.py --test --no-timeout

# Test with custom timeout
python3 motion_standby.py --test --timeout 2

# Test current configuration
python3 motion_standby.py --test --log-level DEBUG

Command Line Usage

Basic Usage

python3 motion_standby.py [options]

Available Flags

Flag Description Example
--config FILE Use custom configuration file --config custom.json
--timeout MINS Override timeout setting --timeout 15
--no-timeout Use 1-minute timeout for testing --no-timeout
--test Enable debug logging for testing --test
--log-level LEVEL Set logging level --log-level DEBUG

Testing Examples

Quick Test (1-minute timeout, verbose output):

python3 motion_standby.py --test --no-timeout

Custom Timeout Test:

python3 motion_standby.py --timeout 5 --log-level DEBUG

Test with Custom Config:

python3 motion_standby.py --config test_config.json --test

Production Run (normal logging):

python3 motion_standby.py

Service Management

Installation

./install_service.sh

The installation script:

  • Creates Python virtual environment
  • Installs dependencies
  • Sets up sudo permissions for display control
  • Creates systemd user service
  • Configures Wayland environment variables

Service Commands

# Start service
systemctl --user start motion-standby

# Stop service
systemctl --user stop motion-standby

# Restart service
systemctl --user restart motion-standby

# Check status
systemctl --user status motion-standby

# Enable auto-start
systemctl --user enable motion-standby

# Disable auto-start
systemctl --user disable motion-standby

# View logs
journalctl --user -u motion-standby -f

# View recent logs
journalctl --user -u motion-standby --since "10 minutes ago"

Troubleshooting Service Issues

Service Won't Start:

# Check service status for error details
systemctl --user status motion-standby

# Check journal logs
journalctl --user -u motion-standby --no-pager

Display Control Not Working:

# Test wlopm manually
wlopm --off "*"
wlopm --on "*"

# Check Wayland environment
echo $WAYLAND_DISPLAY
echo $XDG_RUNTIME_DIR

# Test sudo permissions
sudo -u $USER wlopm --off "*"

Motion Detection Issues:

# Test in debug mode
python3 motion_standby.py --test --log-level DEBUG

How It Works

Architecture

The service consists of three main components:

  1. DisplayController: Manages HDMI display power using wlopm
  2. MotionSensor: Handles LD2410C sensor with intelligent filtering
  3. MotionStandbyService: Coordinates motion detection and display control

Motion Detection Flow

  1. Raw Sensor Reading: Reads GPIO state from LD2410C sensor
  2. Debounce Filter: Prevents electrical noise from causing false readings
  3. Threshold Filter: Requires multiple consecutive positive readings
  4. Duration Filter: Motion must persist for minimum duration
  5. Cooldown Filter: Prevents rapid re-triggering
  6. Valid Motion: Timer resets, display turns on if needed

Display Control

The service uses wlopm (Wayland Light Output Power Management) for reliable display control:

  • Turn Off: wlopm --off "*" - Turns off all displays
  • Turn On: wlopm --on "*" - Turns on all displays
  • Fallback: Uses framebuffer blanking if wlopm unavailable

Threading Model

  • Main Thread: Handles configuration, signals, and service lifecycle
  • Motion Thread: Continuously monitors sensor and detects motion
  • Timeout Thread: Monitors inactivity timeout and controls display

Troubleshooting

Common Issues

Display doesn't turn off/on:

  • Check that wlopm is installed: which wlopm
  • Verify Wayland environment: echo $WAYLAND_DISPLAY
  • Test manually: wlopm --off "*"

Motion not detected:

  • Check sensor wiring (RX/TX for UART communication)
  • Enable debug logging: --log-level DEBUG
  • Verify sensor power: LD2410C should have power LED
  • Check UART communication in logs

Too many false positives:

  • Increase detection_threshold (try 7-8)
  • Increase motion_duration_min (try 4-5 seconds)
  • Increase cooldown_period (try 15-20 seconds)

Service fails to start:

  • Check virtual environment: ls .venv/bin/python
  • Verify permissions: ls -l motion_standby.py
  • Check logs: journalctl --user -u motion-standby

Debug Mode

Enable verbose logging to troubleshoot issues:

python3 motion_standby.py --test --log-level DEBUG

This shows:

  • Raw sensor readings
  • Filter states
  • Motion detection logic
  • Display control commands
  • Timing information

Log Analysis

Normal Operation:

INFO - Motion sensor initialized - Pin:15, Threshold:5, Duration:3.0s, Cooldown:10.0s
INFO - Display controller initialized using wlopm
INFO - Motion Standby Service started successfully
INFO - MOTION DETECTED - Timer reset (30 minutes)
INFO - Standby timeout reached - turning off display
INFO - Display turned OFF

Motion Detection Issues:

DEBUG - Raw sensor reading: True
DEBUG - Recent positives: 3/10 (threshold: 5)
DEBUG - Motion duration: 1.2s (minimum: 3.0s)
DEBUG - Still in cooldown period

Dependencies

  • Python 3.7+: Core runtime
  • gpiozero: GPIO control library
  • pyserial: UART communication for LD2410C sensor
  • wlopm: Wayland display power management
  • systemd: Service management (Linux)

License

This project is released under the MIT License. See LICENSE file for details.

Note

AI made this, I just told it what to do for a very specific use case.

About

Project to have a LD2410C sensor control a display based upon motion detection

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published