# Pi-hole E-Paper Display
**A beautiful, professional dashboard for your Pi-hole stats on a Waveshare E-Paper display** [![Python Version](https://img.shields.io/badge/python-3.6+-blue.svg)](https://www.python.org/downloads/) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) [![Pi-hole](https://img.shields.io/badge/Pi--hole-Compatible-red.svg)](https://pi-hole.net/) ![Pi-hole Stats Display](https://img.shields.io/badge/Display-264x176-lightgrey.svg)
--- ## Overview This project displays real-time Pi-hole statistics on a Waveshare 2.7" E-Paper display with a clean, grid-based layout inspired by professional dashboard designs. Perfect for monitoring your network's ad-blocking performance at a glance. ### Features - **6-Block Grid Layout** - Clean 3×2 design showing comprehensive metrics - **Pi-hole Statistics** - Ads blocked, DNS queries, block percentage, and active devices - **System Monitoring** - Real-time CPU usage and system uptime - **Real-time Updates** - Auto-refreshes every 5 minutes (configurable) - **Flexible Data Sources** - Supports both Pi-hole CLI and HTTP API - **Smart Font Detection** - Automatically finds and uses the best available fonts - **SSH Support** - Can fetch stats from remote Pi-hole instances - **Preview Mode** - Test without physical display hardware - **Customizable Branding** - Add your own title/name to the display --- ## Display Layout The display uses a 6-block grid layout (3 columns × 2 rows) showing comprehensive statistics: ``` ┌──────────────────────────────────────────────────────┐ │ ○ Your Network Name 2025-12-14 ● │ ├─────────────────┬─────────────────┬──────────────────┤ │ │ │ │ │ 1,234 │ 12,345 │ 10.5% │ │ Blocked │ Queries │ Percent │ │ │ │ │ ├─────────────────┼─────────────────┼──────────────────┤ │ │ │ │ │ 15 │ 12.3% │ 5d 12h │ │ Devices │ CPU │ Uptime │ │ │ │ │ └─────────────────┴─────────────────┴──────────────────┘ ``` **Top Row:** - **Blocked** - Total ads blocked today - **Queries** - Total DNS queries today - **Percent** - Percentage of queries blocked **Bottom Row:** - **Devices** - Number of active devices protected - **CPU** - Current CPU usage percentage - **Uptime** - System uptime (days/hours format) --- ## Requirements ### Hardware - Raspberry Pi (or any Linux system with GPIO) - Waveshare 2.7" E-Paper Display (Model: epd2in7b_V2) - Pi-hole installed and running --- ## Prerequisites ### 1. Update and upgrade ```bash sudo apt update && sudo apt upgrade sudo reboot ``` ### 2. Pi-hole installation ```bash curl -sSL https://install.pi-hole.net | bash sudo pihole -g ``` ### 3. Enable SPI for e-paper display ```bash sudo raspi-config # Select --> Interfaces --> SPI --> enable sudo reboot ``` ### 4. Verify python3 and install dependencies ```bash # Single line sudo apt install -y python3-pip python3-pil python3-numpy python3-spidev python3-gpiozero python3-psutil # Individual sudo apt install python3-pip sudo apt install python3-pil sudo apt install python3-numpy sudo apt install python3-spidev sudo apt install python3-gpiozero sudo apt install python3-psutil ``` --- ## Installation ### 1. Clone or Download ```bash git clone https://gitea.bingadventures.com/mbtech/epaper-pihole cd epaper-pihole ``` ### 2. Install Waveshare E-Paper Library ```bash # Download the Waveshare library # Clone with sparse checkout enabled git clone --depth 1 --filter=blob:none --sparse \ https://github.com/waveshare/e-Paper.git cd e-Paper # Checkout only the waveshare_epd directory git sparse-checkout set RaspberryPi_JetsonNano/python/lib/waveshare_epd # Now copy just that directory into your project # example:: cp -r RaspberryPi_JetsonNano/python/lib/waveshare_epd ~/epaper-pihole/ cp -r RaspberryPi_JetsonNano/python/lib/waveshare_epd # normally I install into the home directory ``` ### 3. Update Configuration Edit `epaper-pihole.py` and configure the following settings: ```python # Choose your data source USE_CLI = True # True = use pihole command, False = use HTTP API # For SSH mode (remote Pi-hole) USE_SSH = False SSH_HOST = "user@" # For HTTP API mode PIHOLE_HOST = "" # Your Pi-hole IP address PIHOLE_API_KEY = "" # Optional, for authenticated endpoints # Display settings REFRESH_INTERVAL = 300 # Seconds between updates (5 minutes) # Paths WAVESHARE_LIB_PATH = '/home//epaper-pihole/waveshare_epd' # Path to Waveshare library PREVIEW_IMAGE_PATH = '/home//pihole_display.png' # Path for preview image output # Branding DISPLAY_TITLE = "Your Network Name" # Change to your name! ``` **Note:** All paths are now configurable in the configuration section. Update `WAVESHARE_LIB_PATH` and `PREVIEW_IMAGE_PATH` to match your system. ### 4. Run the Script ```bash # Make executable chmod +x epaper-pihole.py # Run directly python3 epaper-pihole.py # Or run in background nohup python3 epaper-pihole.py & ``` --- ## Configuration Modes ### CLI Mode (Recommended) Uses the `pihole` command-line tool directly. Requires `sudo` access. **Pros:** - More reliable - No API key needed - Works with all Pi-hole versions **Setup:** ```python USE_CLI = True USE_SSH = False # Set True for remote Pi-hole ``` ### HTTP API Mode Uses Pi-hole's web API endpoint. **Pros:** - No sudo required - Works remotely without SSH **Setup:** ```python USE_CLI = False PIHOLE_HOST = "" PIHOLE_API_KEY = "" # Get from Pi-hole settings ``` --- ## Auto-Start on Boot ### Using systemd this works but if enabled than manual running of the script will fail ### Stop service then you can run manually again Create a service file: ```bash sudo nano /etc/systemd/system/pihole-display.service ``` Add the following: ```ini [Unit] Description=Pi-hole E-Paper Display After=network.target [Service] Type=simple User= ## make sure you have the correct user name WorkingDirectory=/home//pihole-epaper ## Make sure proper directory ExecStart=/usr/bin/python3 /home//pihole-epaper/epaper-pihole.py ## Again proper directory Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` Enable and start: ```bash sudo systemctl enable pihole-display.service sudo systemctl start pihole-display.service sudo systemctl status pihole-display.service ``` --- ## Preview Mode Run without physical display hardware for testing: ```bash python3 epaper-pihole.py ``` If the Waveshare library isn't detected, it automatically saves preview images to the path specified in `PREVIEW_IMAGE_PATH` (default: `/home/pi/pihole_display.png`). --- ## Troubleshooting ### Display Not Updating - Check GPIO connections - Verify Waveshare library installation - Check display model matches (epd2in7b_V2) ### No Pi-hole Data - **CLI Mode**: Ensure `sudo pihole` commands work - **HTTP API Mode**: Verify Pi-hole host and API key - **SSH Mode**: Test SSH connection manually ### Font Issues The script auto-detects fonts in this priority: 1. DejaVu Sans 2. Liberation Sans 3. FreeSans 4. Default fallback To install fonts: ```bash sudo apt-get install fonts-dejavu fonts-liberation ``` ### System Stats Not Showing - **CPU shows 0% or N/A**: Install `psutil` for better CPU monitoring. - **Uptime shows N/A**: Ensure `uptime` command is available on your system - **Remote system via SSH**: Make sure SSH commands can execute without password (use SSH keys) --- ## Customization ### Change Refresh Interval ```python REFRESH_INTERVAL = 600 # 10 minutes ``` ### Modify Display Title ```python DISPLAY_TITLE = "My Network Shield" ``` ### Update Paths ```python WAVESHARE_LIB_PATH = '/custom/path/to/waveshare_epd' PREVIEW_IMAGE_PATH = '/custom/path/to/preview.png' ``` ### Adjust Font Sizes In the `create_display_image()` function (around line 200): ```python font_title = ImageFont.truetype(fonts['bold'], 20) # Header font_huge = ImageFont.truetype(fonts['bold'], 32) # Main numbers font_large = ImageFont.truetype(fonts['bold'], 24) # Secondary numbers font_small = ImageFont.truetype(fonts['regular'], 12) # Labels ``` --- ## Code Quality The code has been optimized with the following improvements: - ✅ **6-block layout** - Displays 6 metrics in a clean 3×2 grid (Pi-hole + system stats) - ✅ **System monitoring** - CPU usage and uptime tracking with fallback methods - ✅ **Configurable paths** - All file paths are now in the configuration section - ✅ **Comprehensive comments** - Well-documented code with clear explanations - ✅ **Proper exception handling** - Specific exception types instead of bare except clauses - ✅ **Clean code** - Removed commented-out code and unused lines - ✅ **Main execution** - Proper `if __name__ == "__main__"` block with `main()` call --- ## Console Output When running, you'll see output like: ```text Pi-hole E-Paper Display - Binglab Style (6-Block Layout) ============================================================ Fetching Pi-hole stats... Fetching system stats... Queries: 12,345 Blocked: 1,234 (10.52%) Devices: 15 CPU: 12.3% Uptime: 5d 12h Using fonts: DejaVuSans-Bold.ttf, DejaVuSans.ttf Updating display... ✓ Display updated Next update in 300 seconds... ``` --- ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. --- ## License This project is open source. Feel free to use and modify as needed. --- ## Credits - **Waveshare** - E-Paper display hardware and libraries - **Pi-hole** - Network-wide ad blocking - **Binglab** - Design inspiration --- ## Support For issues and questions: - Check the troubleshooting section - Review Pi-hole documentation - Check Waveshare E-Paper documentation ---
**Made with ☕ for a cleaner internet** [Pi-hole](https://pi-hole.net/) | [Waveshare](https://www.waveshare.com/) | [Python](https://www.python.org/)