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:
- Hardware selection criteria for low-power dashboards
- ESPHome configuration for e-paper displays
- Proxmox API integration for resource monitoring
- Home Assistant sensor data extraction
- Secure authentication patterns for API communications
- 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
Solution | Power Draw | Refresh Rate | Visibility | Integration Depth | Cost |
---|---|---|---|---|---|
Grafana + LCD Monitor | 15-30W | 1-5s | Excellent | High | $100+ |
Tablet Dashboard | 2-5W | 1-5s | Good | Medium | $50-$300 |
e-Paper Custom | 0.02-0.3W | 2-15s | Sunlight OK | Custom | $40-$100 |
SSH Terminal | <0.1W | Manual | Poor | Low | $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
- Hypervisor Health Monitoring: Real-time CPU/memory usage across Proxmox nodes
- Service Status Dashboard: HA entity states (sensors, switches, binary sensors)
- Environmental Tracking: Temperature/humidity graphs from HA-connected sensors
- Security Overview: VPN status, intrusion detection alerts
- Resource Allocation: LXC container memory usage at a glance
PREREQUISITES
Hardware Requirements
- Seeed Studio XIAO 7.5” e-Paper Display (BW)
- USB-C Power Supply (5V/1A minimum)
- WiFi Network with 2.4GHz Support
- 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
- Dedicated VLAN for IoT devices
- Firewall rules restricting ESP32 access to:
- Proxmox API (port 8006)
- Home Assistant API (port 8123)
- NTP (port 123 UDP)
- DNS (port 53 UDP)
- 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
- Validate YAML configuration:
1
esphome compile epaper-dashboard.yaml
- Flash device via USB:
1
esphome run epaper-dashboard.yaml
- 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
- API Token Restrictions:
- Proxmox: Read-only access with
PVEAuditorRole
- Home Assistant: Scope-limited long-lived tokens
- Proxmox: Read-only access with
- 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
- Secure Communication:
- Use HTTPS for all API endpoints
- Implement ESPHome’s
ota_password
feature - Rotate API tokens quarterly
Performance Optimization
- Partial Refresh Configuration: ```yaml display:
- platform: waveshare_epaper partial_updating: true full_update_every: 24 # Full refresh every 24 partial updates ```
- 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 “ ```
- 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
- 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);
- 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!"); }
- 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
- Dashboard Page Rotation Control: ```yaml switch:
- platform: template name: “Force Page Update” turn_on_action:
- lambda: |- last_page_change = 0; // Triggers immediate page rotation ```
- platform: template name: “Force Page Update” turn_on_action:
- 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
- Log Monitoring:
1 2
# Tail ESPHome logs esphome logs epaper-dashboard.yaml
Backup Strategy
- 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"
- **Secure Token Storage