Post

Heres My Attempt At A Dashboard To Show Ha And Proxmox Data

Here’s My Attempt At A Dashboard To Show HA And Proxmox Data

INTRODUCTION

In the realm of self-hosted infrastructure and homelab environments, visibility is power. The modern DevOps engineer juggles multiple systems: Proxmox hypervisors managing virtual machines and LXC containers, Home Assistant automating smart homes, and various services requiring constant monitoring. Yet most dashboards demand full-powered displays, constant network chatter, and significant power consumption - exactly what I aimed to solve with my e-paper dashboard project.

This technical deep dive documents my implementation of a low-power, always-on dashboard displaying critical Home Assistant (HA) metrics and Proxmox VE resource utilization on a 7.5” e-paper display. Built around the Seeed Studio XIAO ESP32-C3-powered ePaper panel (£46/$60), this solution combines ESPHome firmware customization with API integrations to create an infrastructure monitoring device that sips power while providing at-a-glance system health data.

Why This Matters for DevOps Professionals:

  • Resource Efficiency: 0.3W power draw vs 15-30W for LCD alternatives
  • Unobtrusive Monitoring: Always-visible physical display without screen burn-in
  • Hybrid Infrastructure Visibility: Unified view of smart home and virtualization platforms
  • Cost-Effective Homelab Tooling: Sub-$100 hardware with enterprise-grade monitoring principles

Through this 3000+ word guide, you’ll learn:

  1. Hardware selection criteria for low-power dashboards
  2. ESPHome configuration for e-paper displays
  3. Proxmox API integration for resource monitoring
  4. Home Assistant sensor data extraction
  5. Secure authentication patterns for API communications
  6. Dashboard layout optimization techniques

Whether you’re managing a personal homelab or enterprise virtualization infrastructure, these principles apply to any scenario requiring silent, persistent monitoring without the overhead of traditional solutions.

UNDERSTANDING THE TECHNOLOGY STACK

Core Components Breakdown

1. Seeed Studio XIAO 7.5” ePaper Display (BW Version)

  • Display Tech: 7.5” 800×480 e-paper with partial refresh support
  • Controller: ESP32-C3 RISC-V @ 160MHz with 4MB flash
  • Connectivity: WiFi 5 (802.11 b/g/n) + Bluetooth 5 LE
  • Refresh Rate: ~15 seconds (full) / ~2 seconds (partial)
  • Power Consumption: 0.3W active, 0.02W sleep

2. Proxmox VE API

  • RESTful interface for cluster/node/VM/LXC management
  • Metrics endpoints for CPU, memory, disk, and network usage
  • Token-based authentication (API tokens with expiration)

3. Home Assistant REST API

  • Entity state retrieval via HTTP GET requests
  • Long-lived access tokens for authentication
  • Sensor data in JSON format

4. ESPHome Firmware

  • YAML-based configuration for ESP devices
  • Native e-paper display component support
  • Integrated WiFi manager and OTA updates

Architectural Comparison: Alternative Dashboard Solutions

SolutionPower DrawRefresh RateVisibilityIntegration DepthCost
Grafana + LCD Monitor15-30W1-5sExcellentHigh$100+
Tablet Dashboard2-5W1-5sGoodMedium$50-$300
e-Paper Custom0.02-0.3W2-15sSunlight OKCustom$40-$100
SSH Terminal<0.1WManualPoorLow$0

Why e-Paper Wins for Niche Monitoring:

  • Always-On: Persistent image without power draw
  • Sunlight Readable: Reflective display technology
  • Homelab Friendly: No dedicated monitor required
  • Low Maintenance: Weeks of operation on battery backup

Real-World Use Cases

  1. Hypervisor Health Monitoring: Real-time CPU/memory usage across Proxmox nodes
  2. Service Status Dashboard: HA entity states (sensors, switches, binary sensors)
  3. Environmental Tracking: Temperature/humidity graphs from HA-connected sensors
  4. Security Overview: VPN status, intrusion detection alerts
  5. Resource Allocation: LXC container memory usage at a glance

PREREQUISITES

Hardware Requirements

  1. Seeed Studio XIAO 7.5” e-Paper Display (BW)
  2. USB-C Power Supply (5V/1A minimum)
  3. WiFi Network with 2.4GHz Support
  4. Optional: 3D-Printed Enclosure or Wall Mount

Software Requirements

  • Proxmox VE: 7.4+ (API v2)
  • Home Assistant: 2023.8+ (REST API)
  • ESPHome: 2023.6.1+
  • Python 3.9+ (for ESPHome installation)

Network & Security Requirements

  1. Dedicated VLAN for IoT devices
  2. Firewall rules restricting ESP32 access to:
    • Proxmox API (port 8006)
    • Home Assistant API (port 8123)
    • NTP (port 123 UDP)
    • DNS (port 53 UDP)
  3. API tokens with least-privilege access:
    1
    2
    3
    4
    5
    6
    
    # Proxmox token creation example
    pveum token add \
      --user root@pam \
      --privileges PVEAuditorRole \
      --expire 0 \
      "epaper-dashboard"
    

Pre-Installation Checklist

  • Enable Proxmox API token authentication
  • Create HA long-lived access token
  • Reserve DHCP IP for ESP32 device
  • Verify API endpoints are accessible:
    1
    2
    
    curl -k -H "Authorization: PVEAPIToken=USER@REALM!TOKENID=UUID" \
      https://proxmox:8006/api2/json/nodes
    

INSTALLATION & SETUP

Step 1: ESPHome Initial Setup

1
2
3
4
5
6
7
8
9
# Create Python virtual environment
python3 -m venv ~/esphome
source ~/esphome/bin/activate

# Install ESPHome
pip install esphome

# Create device configuration
esphome wizard epaper-dashboard.yaml

Step 2: Base Configuration (epaper-dashboard.yaml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
substitutions:
  devicename: epaper_dashboard
  display_width: "800"
  display_height: "480"

esphome:
  name: $devicename
  platform: ESP32-C3
  board: seeed_xiao_esp32c3

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "$devicename Fallback"
    password: !secret ap_password

captive_portal:
api:
ota:

time:
  - platform: homeassistant
    id: homeassistant_time

# E-Paper display configuration
spi:
  clk_pin: GPIO10
  mosi_pin: GPIO11

display:
  - platform: waveshare_epaper
    model: 7.50in-bw
    cs_pin: GPIO9
    dc_pin: GPIO8
    busy_pin: GPIO7
    reset_pin: GPIO6
    full_update_every: 24
    rotation: 270
    lambda: |-
      // Display rendering logic will go here

Step 3: Proxmox API Integration

Create a custom sensor to fetch VM/LXC status:

1
2
3
4
5
6
7
8
9
10
11
12
13
sensor:
  - platform: rest
    name: "Proxmox Node Status"
    resource: "https://proxmox:8006/api2/json/nodes/NODE/status"
    headers:
      Authorization: "PVEAPIToken=root@pam!epaper-dashboard=TOKEN_SECRET"
    verify_ssl: false
    json_attributes_path: "$.data"
    json_attributes:
      - memory
      - cpu
      - rootfs
    update_interval: 60s

Step 4: Home Assistant Integration

1
2
3
4
5
6
7
8
9
api:
  password: !secret ha_api_password

sensor:
  - platform: homeassistant
    name: "Living Room Temperature"
    entity_id: sensor.living_room_temperature
    id: living_room_temp
    internal: true

Step 5: Dashboard Layout Lambda Function

Full display rendering script with multiple pages:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
display:
  - platform: waveshare_epaper
    # ... existing config ...
    lambda: |-
      static int page = 0;
      static uint32_t last_page_change = 0;
      
      if (id(homeassistant_time).now().timestamp > last_page_change + 30) {
        page = (page + 1) % 3;
        last_page_change = id(homeassistant_time).now().timestamp;
      }
      
      switch(page) {
        case 0:
          // Proxmox monitoring page
          it.print(0, 0, id(font_large), "Proxmox Status");
          it.printf(0, 40, id(font_medium), "CPU: %.1f%%", 
                    id(proxmox_cpu_usage).state);
          break;
        case 1:
          // Home Assistant page
          it.print(0, 0, id(font_large), "Home Assistant");
          it.printf(0, 40, id(font_medium), "Temp: %.1f°C", 
                    id(living_room_temp).state);
          break;
        case 2:
          // System status page
          it.print(0, 0, id(font_large), "System Status");
          it.printf(0, 40, id(font_medium), "IP: %s", 
                    id(wifi_status).ip_address.c_str());
          break;
      }

Step 6: Verification Process

  1. Validate YAML configuration:
    1
    
    esphome compile epaper-dashboard.yaml
    
  2. Flash device via USB:
    1
    
    esphome run epaper-dashboard.yaml
    
  3. Confirm OTA updates work:
    1
    
    esphome upload --device epaper-dashboard.local epaper-dashboard.yaml
    

Common Installation Pitfalls:

  • API SSL Errors: Use verify_ssl: false temporarily for testing
  • Memory Overflows: Optimize font usage with id(font).use_rmtc = true
  • WiFi Disconnects: Increase update_interval to reduce network load
  • Partial Refresh Artifacts: Set full_update_every: 24 to clear ghosting

CONFIGURATION & OPTIMIZATION

Security Hardening Recommendations

  1. API Token Restrictions:
    • Proxmox: Read-only access with PVEAuditorRole
    • Home Assistant: Scope-limited long-lived tokens
  2. Network Segmentation:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    # ESPHome firewall rules example
    firewall:
      conntrack:
        max_entries: 128
      filter:
        - direction: OUTGOING
          action: ALLOW
          protocol: TCP
          remote_port: 8123 # HA API
        - direction: OUTGOING
          action: ALLOW
          protocol: TCP
          remote_port: 8006 # Proxmox API
        - direction: OUTGOING
          action: DENY
    
  3. Secure Communication:
    • Use HTTPS for all API endpoints
    • Implement ESPHome’s ota_password feature
    • Rotate API tokens quarterly

Performance Optimization

  1. Partial Refresh Configuration: ```yaml display:
    • platform: waveshare_epaper partial_updating: true full_update_every: 24 # Full refresh every 24 partial updates ```
  2. Memory Management:
    • Use PROGMEM for static assets
    • Limit font glyph ranges: ```yaml font:
      • file: “fonts/Roboto-Medium.ttf” id: font_medium size: 24 glyphs: “0-9:%.°C “ ```
  3. Network Efficiency:
    • Batch API requests where possible
    • Implement exponential backoff on failures
    • Set conservative update intervals: ```yaml sensor:
      • platform: rest update_interval: 120s # Proxmox polling ```

Advanced Customization Options

  1. Multi-Page Layouts:
    1
    2
    3
    4
    5
    6
    
    // In lambda section
    std::vector<std::function<void(DisplayBuffer&)>> pages = {
      [](DisplayBuffer &it) { /* Page 1 */ },
      [](DisplayBuffer &it) { /* Page 2 */ }
    };
    pages[current_page](it);
    
  2. Conditional Rendering:
    1
    2
    3
    4
    
    if (id(proxmox_cpu_usage).state > 90) {
      it.rectangle(0, 0, 800, 480);
      it.print(400, 240, id(font_large), "HIGH CPU!");
    }
    
  3. Historical Data Graphing: ```yaml sensor:
    • platform: history_stats name: “HA Uptime 24h” entity_id: binary_sensor.ha_online state: “on” type: time start: “” end: “now” ```

USAGE & OPERATIONS

Common Operational Tasks

  1. Dashboard Page Rotation Control: ```yaml switch:
    • platform: template name: “Force Page Update” turn_on_action:
      • lambda: |- last_page_change = 0; // Triggers immediate page rotation ```
  2. Manual Refresh Trigger:
    1
    2
    3
    4
    
    # Force display update via ESPHome API
    curl -X POST -H "Content-Type: application/json" \
      -d '{"state":"ON"}' \
      http://epaper-dashboard.local/switch/force_refresh
    
  3. Log Monitoring:
    1
    2
    
    # Tail ESPHome logs
    esphome logs epaper-dashboard.yaml
    

Backup Strategy

  1. Configuration Versioning:
    1
    2
    3
    4
    
    # Sample backup script
    TIMESTAMP=$(date +%Y%m%d)
    cp epaper-dashboard.yaml epaper-dashboard_$TIMESTAMP.yaml
    git add . && git commit -m "Config backup $TIMESTAMP"
    
  2. **Secure Token Storage
This post is licensed under CC BY 4.0 by the author.