Build a Wall-Mounted Maker Dashboard: Aggregating Your Print Farm, Security, and Home Server on One CYD Panel
Our CYD dashboard guide covered the base display setup with a generic data source. This project makes it specific and genuinely useful: pulling real, live status from everything else you've built — your 3D printer farm, your home server, your security system — into one wall-mounted panel that shows your whole maker setup's status at a glance.
What This Actually Solves
If you've built several of the projects on this site — OctoPrint/Klipper print monitoring, a Pi home server, Frigate security cameras, a LoRa sensor network — each one has its own app or web dashboard. Checking on everything means opening several different interfaces. A single wall panel that aggregates the important bits from all of them removes that friction entirely: glance at the wall, know the state of everything.
Data Sources to Aggregate
SourceWhat to PullAPI OctoPrint/Klipper (print server)Current print progress, time remaining, bed/nozzle tempsOctoPrint REST API, or Moonraker for Klipper FrigateRecent detection events, camera online statusFrigate's REST API Home AssistantAny exposed sensor — temperature, security status, LoRa sensor readings if routed through HAHA REST API with a long-lived access token Pi home serverDisk space, uptime, service healthA small custom status endpoint — simplest to just write a lightweight script exposing whatever you care about as JSONBuilding a Unified Status Endpoint
Rather than having the CYD make several separate API calls to different services (more code complexity, more failure points, slower refresh), a cleaner pattern is a small aggregator script on your Pi that polls all your actual services and exposes one combined JSON endpoint for the CYD to hit:
# aggregator.py — run as a simple Flask app on your Pi home server from flask import Flask, jsonify import requests app = Flask(__name__) @app.route('/api/dashboard') def dashboard_status(): status = {} try: printer = requests.get('http://localhost:7125/printer/objects/query?print_stats', timeout=2).json() status['print_progress'] = printer.get('result', {}).get('status', {}).get('print_stats', {}).get('progress', 0) except Exception: status['print_progress'] = None try: frigate = requests.get('http://localhost:5000/api/stats', timeout=2).json() status['cameras_online'] = len(frigate.get('cameras', {})) except Exception: status['cameras_online'] = None try: ha = requests.get( 'http://localhost:8123/api/states/sensor.outdoor_temperature', headers={'Authorization': 'Bearer YOUR_HA_TOKEN'}, timeout=2 ).json() status['outdoor_temp'] = ha.get('state') except Exception: status['outdoor_temp'] = None return jsonify(status) if __name__ == '__main__': app.run(host='0.0.0.0', port=9000)Each source is wrapped in its own try/except so one service being temporarily down doesn't break the whole aggregated response — the CYD just gets a null for that field and can display "offline" rather than the entire dashboard failing to load.
CYD Firmware: Multi-Field Display
Extend the base CYD dashboard pattern to render multiple status fields in a clean layout:
void fetchAndDisplay() { HTTPClient http; http.begin("http://your-pi-ip:9000/api/dashboard"); int code = http.GET(); if (code == 200) { JsonDocument doc; deserializeJson(doc, http.getString()); tft.fillScreen(TFT_BLACK); tft.setTextSize(2); tft.setCursor(10, 10); tft.setTextColor(TFT_GREEN); tft.println("Print: " + String((int)(doc["print_progress"].as<float>() * 100)) + "%"); tft.setCursor(10, 40); int cams = doc["cameras_online"]; tft.setTextColor(cams > 0 ? TFT_GREEN : TFT_RED); tft.println("Cameras: " + String(cams) + " online"); tft.setCursor(10, 70); tft.setTextColor(TFT_WHITE); tft.println("Outdoor: " + doc["outdoor_temp"].as<String>() + "F"); } http.end(); }Color-coding status (green for healthy, red for a service that's down or reporting null) makes the panel genuinely glanceable — you want to be able to tell "everything's fine" versus "something needs attention" from across the room, not by reading detailed numbers.
Touch Interaction: Drill-Down Views
With the touchscreen, add multiple dashboard "pages" — a summary view by default, with tap zones that switch to a more detailed view of one subsystem:
enum DashboardView { SUMMARY, PRINT_DETAIL, CAMERA_DETAIL }; DashboardView currentView = SUMMARY; // in touch handler: if (currentView == SUMMARY && touchedPrintZone(x, y)) { currentView = PRINT_DETAIL; renderPrintDetail(); }This keeps the default view clean and glanceable while still giving you access to deeper detail (which specific print is running, individual camera thumbnails, etc.) without needing to grab your phone.
Alerting on the Dashboard Itself
Beyond passive status, use the same aggregator pattern to surface things that need attention — a print that failed, a camera that's gone offline, a sensor reporting an out-of-range value. A simple approach: have the aggregator script flag an "alerts" array, and have the CYD firmware check for any entries and display a prominent banner rather than the normal summary view when something needs attention:
JsonArray alerts = doc["alerts"]; if (alerts.size() > 0) { tft.fillScreen(TFT_RED); tft.setTextColor(TFT_WHITE); tft.setCursor(10, 10); tft.println("ALERT:"); tft.println(alerts[0].as<String>()); } else { renderNormalDashboard(); }Refresh Rate Considerations
Data TypeReasonable Refresh Interval Print progress30–60 seconds — changes slowly enough that frequent polling adds little value Security/camera status10–30 seconds — you want alerts to feel timely Environmental sensors (temp, etc.)1–5 minutes — these change gradually, no need for rapid pollingRather than polling everything at the same interval, consider a smarter loop that checks fast-changing/high-priority data more frequently than slow-changing data — though for a first build, a single uniform 30-second refresh of the whole aggregated endpoint is a perfectly reasonable starting point before optimizing further.
This is really the payoff project for everything else built across a maker setup — the individual pieces (print server, security system, sensor network) are each useful on their own, but a single panel that pulls them all together into one glance is what actually changes daily behavior from "check five apps" to "look at the wall."
Related Guides
- DIY Home Security System: Combining Raspberry Pi, ESP32 Sensors, and Flipper Zero
- Build a Wall-Mounted Dashboard with the ESP32 Cheap Yellow Display (CYD)
- Raspberry Pi Security Camera/NVR with Frigate
- MQTT and Node-RED on Raspberry Pi: Visual Automation for ESP32 Sensor Networks
- Scaling Up: A Multi-Node LoRa Sensor Network with a Raspberry Pi Gateway
- Build a Local AI Security Camera System with Frigate NVR on a Raspberry Pi
- Running Frigate NVR on Raspberry Pi for Security Cameras
- Running Home Assistant on a Raspberry Pi 4