Browse documentation

🧭 Start Here

Blackcap Overview ✨ Blackcap Feature Catalog Installation First Run

🚀 Deploy Blackcap

Platform Stacks and Raspberry Pi Hardware Raspberry Pi Deployment Raspberry Pi Client Services GCP Deployment Application Updates Environment Variables and Secrets Reverse Proxy and TLS Background Jobs and Schedules

🛠️ Administer Blackcap

Organizations Users, Permissions, and Authentication Configuration Workspace Backups and Restore Database Administration Regression Testing Performance and Job Status Audit, Access Activity, and Logging GeoIP and Access Location Data Retention and Purge Support Requests API Tester and Postman Instance Reporting

🍽️ Use Recipes

Recipes and the Recipe Library Recipe Import and Discovery Recipe Editing and Cache Artifacts Recipe Sharing Social Recipe Import AI Recipe Image Generation

📅 Plan Meals

Meal Planner

🛒 Use Shopping Lists

Shopping Lists and Shop a List External and Household Shopping 🧩 Chrome Extension Shop With

🧺 Manage Kitchen Inventory

🧺 Kitchen Inventory

🖥️ Use Displays

Displays and Connections Assigning and Scheduling Display Content Remote Pi Client E-Ink Rendering Menu Refresh and Rendering Noun Project Footer Images

🧑‍🍳 Cook with Let’s Cook

🧑‍🍳 Let’s Cook 🧑‍🍳 Let’s Cook Controls and Timers

🤖 Use and Administer AI

🤖 AI in Blackcap 🤖 AI Providers and Connections 🤖 AI Seeds and Usage

🧩 Use the Chrome Extension

🧩 Blackcap Chrome Extension 🧩 Chrome Extension Recipe Capture 🧩 Chrome Extension Shop With 🧩 Chrome Extension Release and Privacy

🎮 Play Games

🎮 Games and Trivia

🔌 Integrations

Email Integration Cloud Storage Integrations Voice Assistants Shop With Integrations Authentication Providers

⚙️ Develop Blackcap

Application Architecture Database Service and Data Access SQLite and PostgreSQL Database Migrations Background Job Architecture Testing API Architecture Security and Organization Scoping UI, Icons, and Documentation Assets Blackcap-Safe Emoji Documentation Standards Terminology

⚠️ Troubleshoot Blackcap

⚠️ Troubleshooting Deployment Troubleshooting Display Troubleshooting Recipe Import Troubleshooting 🤖 AI Troubleshooting Backup Troubleshooting Database Troubleshooting Diagnostic Organization Clones Support Requests

Raspberry Pi Client Services

Audience: Deployment Administrator, System Admin, Support, Developer
Related documentation: Remote Pi Client, Raspberry Pi deployment, Background jobs and schedules, E-ink rendering

Deployment roles

A Raspberry Pi can run Blackcap in three materially different roles:

  1. Pi server with attached e-ink — hosts the Flask/Gunicorn application and SQLite database and owns a local physical panel.
  2. Pi server without attached e-ink — hosts Blackcap and may deliver content to remote clients or hosted displays.
  3. Client-only Pi — does not host the application database or Admin UI; it links its attached panel to another Blackcap server, commonly GCP.

Do not install or enable every service on every Pi. The deployment scripts choose services according to role, attached hardware, and whether remote Let’s Cook delivery is enabled.

Client-only service topology

blackcap-client.service

This is the primary always-running client service. It launches the client helper in local-attached mode, reads the saved server/display link, polls the server, downloads server-prepared preview or panel transport, verifies it, writes it to the attached Waveshare panel, reports status, and repeats.

Typical behavior:

  • starts after networking is available;
  • restarts automatically after failure;
  • uses the Blackcap client configuration and linked display token;
  • performs a baseline poll for ordinary content and a faster cadence during active Let’s Cook sessions;
  • reports download, render version, panel readiness, physical-write timing, and error state to the server;
  • never owns the server database or normal server scheduler.

Manage it with:

sudo systemctl status blackcap-client.service --no-pager -l
sudo journalctl -u blackcap-client.service -n 200 --no-pager
sudo systemctl restart blackcap-client.service

The service must run as the deployment user with permission to read its configuration and access SPI/GPIO. Keep the linked client token private.

Networking dependency

The client requires working DNS, trusted HTTPS, system time, and outbound access to the Blackcap server. A network-online target does not guarantee that public DNS or the server is already reachable, so the client is designed to retry safely.

Physical panel dependencies

The optimized panel is the Waveshare 13.3-inch Type K four-gray display. The client needs the compatible Waveshare driver, SPI enabled, correct GPIO/SPI access, and the server-prepared transport contract. The display write path must use the shared panel lock so two local processes never drive the panel at the same time.

Server-side services that support remote clients

The following services run on a Blackcap server, not on the client-only Pi.

inky_admin.service or inky_admin.gcp.service

The application service exposes the Admin/Mobile/API surfaces, client-linking and polling endpoints, display state, preview/transport generation, and client diagnostics. On Pi it normally uses the Pi unit and SQLite; on GCP it uses the GCP unit, PostgreSQL through Cloud SQL Auth Proxy, and Gunicorn behind Nginx.

The application service must be healthy for linking, content assignment, and polling. It also authenticates client tokens and prevents a Remote Pi Client from receiving another organization’s content.

Let’s Cook watcher unit names by host

The installer selects the watcher role by deployment mode; the unit names are not identical on every host.

  • Full Pi server with an attached panel: blackcap_lets_cook_timer_refresh.service runs run_lets_cook_timer_refresh.py --watch --interval 10 --quiet for local attached-e-ink refresh coalescing.
  • Full Pi server serving Remote Pi Clients: optional blackcap_lets_cook_remote_client_refresh.service runs --watch --interval 2 --remote-clients --quiet and prepares fast remote-client preview/render versions.
  • GCP server: blackcap_lets_cook_timer_refresh.service is reused as the remote-client preview watcher and runs --watch --interval 2 --remote-clients --quiet; the Pi-only companion blackcap_lets_cook_remote_client_refresh.service is removed.
  • Client-only Pi: neither server-side watcher is installed. The client polls the server and writes the panel; it has no application database from which to generate Let’s Cook state.

Without the remote-client watcher, a Remote Pi Client session can still start, but timer/progress updates may wait for a slower general refresh path. The UI warns administrators when the selected deployment intentionally disabled that watcher.

Do not treat local and remote watcher roles as interchangeable: the local role owns an attached panel refresh, while the remote role prepares server-side output that a linked client later polls and writes.

Managed schedule profiles

A full Pi or GCP server receives the server schedule in /etc/cron.d/blackcap: display refresh every minute, regression-task resume/start every 15 minutes, daily purge, hourly backup-schedule checks, and optional Menu refresh. These are database-backed server operations, not client polling.

A client-only Pi uses the pi-client schedule mode. That mode explicitly disables server Menu refresh, server Let’s Cook watchers, GeoIP update units, and all database-backed server schedules. It may retain only the optional monthly attached-e-ink deep-clean entry when enabled.

inky_menu.py runs on the server according to the selected schedule profile. It captures and renders Menu content for displays, including remote clients. The client only receives the resulting assigned transport; it does not run Playwright/OCR against the organization Menu URL.

Other Pi server services

Depending on deployment role, a Pi server may also use:

  • inky_admin.service — Gunicorn application service;
  • stunnel4.service (or the distribution's stunnel.service) — the recommended Pi HTTPS front end created by deploy_pi.sh;
  • blackcap_geoip_update.service and .timer — monthly local GeoIP database maintenance;
  • blackcap_lets_cook_timer_refresh.service — local attached-panel timer watcher;
  • blackcap_lets_cook_remote_client_refresh.service — remote-client timer watcher;
  • managed cron operations for display refresh, Menu refresh, regression tasks, backups, purge, and optional monthly e-ink deep clean.

Only the services relevant to the selected deployment should be enabled.

What blackcap-client.service does on a full Pi server

The deployment script installs blackcap-client.service when the full Pi server directly drives an attached e-ink panel. Its --local-attached mode does not automatically turn the Pi into a remote client. The process sleeps while the attached display is owned by normal local server content. It becomes active only when that local display is placed in Client mode and linked to another Blackcap server. This prevents the local server renderer and the remote pull client from competing for the same panel.

The service checks local ownership state every five seconds while sleeping. When active, its normal server-directed pull interval defaults to 30 seconds, the heartbeat defaults to 60 seconds, and a successful Let’s Cook physical refresh triggers an immediate follow-up poll so a render produced during the slow e-ink write is not delayed by another full interval.

The same process owns last-known-good preview/transport files, transport verification, the shared panel lock, physical-write acknowledgement, retry/backoff, and local client diagnostics. It must not bypass the server's display token, organization, render-version, or panel-ready contract.

Polling and content lifecycle

The remote client normally polls at a baseline cadence. During active Let’s Cook it uses the faster session cadence and performs a post-refresh recheck so an update created while the slow physical panel refresh was underway is not delayed until another full interval.

The server owns:

  • organization authorization;
  • active/default/scheduled display state;
  • recipe, Meal Planner, Menu, and Let’s Cook rendering;
  • render version and prepared transport;
  • client-link and revocation state.

The client owns:

  • local download and integrity verification;
  • panel-driver conversion where required by the transport contract;
  • the physical e-ink write and lock;
  • local retry/backoff;
  • reporting its last poll, download, physical update, and error.

Linking and secrets

Link the attached display through the client setup flow using the server URL, organization/display selection, and one-time or issued client credential. The saved credential is equivalent to access to that display and should be readable only by the service user.

Revoking or unlinking the display invalidates the client credential. Backups and diagnostic clones must not create a second usable copy of it.

Installation and enablement

Use the repository Pi deployment script/profile rather than hand-installing units in isolation. The installer places unit files, reloads systemd, enables the selected services, and writes the correct schedule profile. After installation:

sudo systemctl daemon-reload
sudo systemctl enable --now blackcap-client.service

Use that direct command only when the unit and client configuration have already been installed correctly. For unit-file changes, follow Blackcap practice and edit the actual file, for example:

sudo nano /etc/systemd/system/blackcap-client.service
sudo systemctl daemon-reload
sudo systemctl restart blackcap-client.service

Service-by-role matrix

Component Pi server + local panel Pi server, no local panel Client-only Pi GCP server
Application service Yes Yes No Yes
SQLite database Usually Usually No No
Cloud SQL Auth Proxy No No No Yes
blackcap-client.service Only when acting as a client Only when acting as a client Yes No
Local Let’s Cook watcher Yes No No No
Remote-client Let’s Cook watcher Optional companion unit Optional companion unit No blackcap_lets_cook_timer_refresh.service in remote mode
Server cron schedule Yes Yes No Yes
Menu capture/render Yes Yes No Yes
Physical panel write Local watcher/render path No Client service No
GeoIP update timer Yes when server schedules are installed Yes when server schedules are installed No Yes when server schedules are installed
TLS reverse proxy Pi TLS approach Pi TLS approach No inbound service required Nginx/Certbot

Troubleshooting sequence

  1. Verify power, SPI, cabling, and the correct panel model.
  2. Verify time, DNS, and HTTPS access from the client.
  3. Check blackcap-client.service status and logs.
  4. Confirm the linked display is active, not revoked, and assigned Client-compatible content.
  5. Compare server Display Details timestamps: last client poll, preview/version, and physical update.
  6. Confirm the server application service is healthy.
  7. For Let’s Cook delay, confirm the remote-client watcher is enabled on the server.
  8. For scheduled content, inspect the server cron/job status rather than the client service.
  9. For a downloaded image that does not reach the panel, inspect panel-ready, transport hash, lock, driver mode, and physical-write logs.

Changes and restarts

Documentation-only changes require no restart. A changed client Python file normally requires copying the file and restarting blackcap-client.service. A changed systemd unit requires direct file update, daemon-reload, restart, and status verification. A server application change normally requires its migrations if any, then an application restart; do not restart the physical client unless its code or configuration changed.

On this page