Prusa-Print-Monitor

Prusa-Print-Monitor

Docker app from jbat66's Repository

Overview

PrusaLink status dashboard with compact, mobile and across-the-room layouts. Change PRINTER_URL and API_KEY before starting. Optional browser alerts require a selected MP3 in the writable Sounds Folder at /sounds and clicking Enable sounds. Optional RTSP/HTTP camera is converted by FFmpeg. Keep this dashboard on your trusted LAN; it has no login.

Prusa Print Monitor

Prusa Print Monitor — version 0.2.16

A Docker dashboard for a PrusaLink printer, designed for UNRAID, phones, a desktop corner or a room display. Uses the same HTTP Digest authentication and status fields as printer-state-display.sh. No printer credentials are sent to the browser.

  • Large color-coded printer state, remaining time and estimated finish.
  • Separate filament-change countdown, connection health and last successful update.
  • Desktop, compact, mobile and across-the-room layouts selectable in the web UI.
  • State-change sounds with mute, acknowledge and full-screen controls.
  • Optional RTSP/HTTP camera converted to browser-viewable MJPEG by FFmpeg.

Support

For setup help, questions, and troubleshooting, use the Prusa Print Monitor support discussion.

Install on UNRAID

The Community Apps template is maintained in jbat66/unraid-templates, alongside the other applications in that existing Community Apps repository. Application code, Docker builds, icons and support remain here. Submit/scan the template repository, rather than registering this code repository separately.

  1. Download the Prusa Print Monitor template. Save it on your UNRAID server at /boot/config/plugins/dockerMan/templates-user/my-prusa-print-monitor.xml.
  2. In UNRAID, open Docker → Add Container, and select Prusa-Print-Monitor from the template list.
  3. Replace X.X.X.X in PRINTER_URL with your printer address and replace PUT-KEY-HERE with your PrusaLink password/API key. Default username is maker.
  4. Set a free host web port (default 8085), apply, and use the container's WebUI menu. Open http://YOUR-UNRAID-IP:8085 from other devices.

Every template setting is visible in basic view. The printer and feature variables appear in the requested order:

Variable Default Instructions
PRINTER_URL http://X.X.X.X/api/v1/status Replace the example IP with your printer IP.
API_USER maker PrusaLink Digest username.
API_KEY PUT-KEY-HERE Replace with your printer key/password.
REFRESH_SECONDS 60 Printer polling interval in seconds.
ALERT false If true, select your host audio file using Sound File.
CAMERA false If true, replace CAMERA_URL with a working stream URL.
CAMERA_URL rtsp://x.x.x.x/live Replace with your actual RTSP/HTTP stream.
ALERT_REPEAT_SECONDS 60 Repeat interval until acknowledged.
REQUEST_TIMEOUT_SECONDS 10 Printer request timeout.
SOUND_FILE /mnt/user/appdata/prusa-print-monitor/sounds/AlarmSoundEffect.mp3 Select the MP3 inside Sounds Folder; the filename is resolved under /sounds.
DEFAULT_LAYOUT desktop Initial non-mobile layout: desktop, compact, mobile, or large (Across the Room). Phones/tablets always start in Mobile.
TZ America/Denver Container timezone; UI times use the browser timezone.

All intervals must be positive integers. The server listens on container port 8085. It exits with a configuration error if alerts are enabled without a readable sound file.

Get the PrusaLink API key from Prusa Connect

  1. Sign in at Prusa Connect and select your printer.
  2. Open that printer's Settings tab and find the API keys / PrusaLink section.
  3. Copy the PrusaLink API key (the local printer credential), rather than the separate Prusa Connect cloud API key. Paste it into this container's API_KEY; put the displayed printer IP into PRINTER_URL.
  4. If no local credential is shown, enable PrusaLink on the printer. On supported MK4/XL-style firmware, open Settings → Network → PrusaLink on the printer: its password is the local PrusaLink API key, and the default username is maker. Generate/reset the local password using the controls offered by your printer/firmware when needed, then copy the new value. Some PrusaLink versions expose credentials through their local web setup instead.

Prusa Connect's Settings tab displays the local credential; generating a separate cloud API key does not create a replacement local PrusaLink password. This dashboard uses HTTP Digest authentication: for older Raspberry Pi PrusaLink installations, use their configured local username/password.

Sources: Prusa's credentials instructions, PrusaLink troubleshooting.

Sounds

Set Sounds Folder to the writable host directory where you want the sound files saved. Default: /mnt/user/appdata/prusa-print-monitor/sounds, mounted at container /sounds. Each time the container starts, it copies missing bundled files into that directory:

  • AlarmSoundEffect.mp3 (default)
  • ClockChimes.mp3
  • Cuckoo.mp3
  • RedAlert.mp3

Existing files are preserved. The startup helper seeds the directory before dropping to user monitor (UID 10001) and starting the dashboard. The four original MP3s are packaged at /app/assets/sounds so the host volume does not hide them.

Sound File defaults to /mnt/user/appdata/prusa-print-monitor/sounds/AlarmSoundEffect.mp3. Select another bundled sound by changing the filename (case-sensitive), or add your own MP3 to Sounds Folder. This entry is the SOUND_FILE variable, not a separate file mount: only its filename is resolved inside /sounds. When moving the host folder, update Sounds Folder and the path displayed in Sound File. There is no ALERT_SOUND_FILE variable.

Set ALERT=true and click Enable sounds in each browser. MP3 plays directly on the viewing device without conversion; the NAS needs no sound hardware. The host directory must allow the startup helper to create missing files, and UID 10001 must be able to read them. Files on a network share with root-squash may require host-side permission changes.

To upgrade from 0.2.8 or earlier, remove the old single-file /sounds mount and replace it with the new writable Sounds Folder directory mount. Add Sound File as the selector variable with your selected filename. An older single-file mount can still play its existing audio, but it cannot receive all four bundled files.

The first successful status is the baseline and does not alert. Every subsequent observed printer state change creates an alert, including changes to PRINTING and IDLE. It repeats at ALERT_REPEAT_SECONDS until Acknowledge. Mute temporarily suppresses sound without acknowledging; unmuting resumes pending alerts. A newer state change requires a new acknowledgment. Each viewing browser manages its own audio and acknowledgment. Reloading establishes a new baseline. Connection failures do not create printer-state alerts. Changes while no browser is open do not sound later. Browsers need an initial user gesture for audio and may suspend background tabs; use an awake foreground display for dependable alerts.

Camera

Set CAMERA=true and configure CAMERA_URL, for example rtsp://user:password@192.168.1.20:554/live. Click Enable Camera to turn the feed on; click Camera Enabled to stop it. The setting allows camera access; feeds start only on request. FFmpeg converts RTSP or HTTP video streams to MJPEG at 3 fps and 960px width. Each viewer consumes one conversion process, limited to four concurrent viewers. Camera URLs and passwords stay on the server. A feed failure shows a message; toggle off/on to reconnect. The server must be able to reach the camera and printer on your LAN.

Display behavior

The browser checks the dashboard every two seconds; the backend polls the printer every REFRESH_SECONDS. Countdown values update every second between polls while PRINTING. PAUSED freezes countdowns and hides the estimated finish. Connection failures retain clearly marked last-known data and freeze countdowns. Missing/invalid times show a dash; a missing or zero filament-change value means no scheduled change is reported. An elapsed filament countdown shows “Change due” until the printer provides an update. Printer state labels are shown as reported, including UNKNOWN or firmware-specific values. Layout choice is saved per browser; narrow screens also adapt automatically.

This is a trusted-LAN dashboard with no user login. Anyone with access to its web port can view printer status, the configured alert audio, and the enabled camera. Do not expose it directly to the internet. Printer credentials are stored in container environment settings, visible to UNRAID administrators.

Build or run yourself

git clone https://github.com/jbat66/Prusa-Print-Monitor.git
cd Prusa-Print-Monitor
cp .env.example .env
# Edit .env with your own printer settings.
# Edit the Compose Sounds Folder bind source if using a different host folder.
docker compose up -d --build

For plain Docker, build with docker build -t prusa-print-monitor ., then:

docker run -d --name prusa-print-monitor --restart unless-stopped \
  -p 8085:8085 --env-file .env \
  -v /mnt/user/appdata/prusa-print-monitor/sounds:/sounds:rw \
  prusa-print-monitor

To run without Docker, Python 3.13 requires no third-party packages: set the environment variables, then run python app.py. Install FFmpeg separately if camera support is enabled. For alerts without Docker, create the /sounds directory, copy in the MP3s, and set SOUND_FILE to your chosen filename. /health checks the web service, not the printer; /api/status reports printer connectivity separately.

Development checks

python -m unittest discover -s tests -v
node --test tests/dashboard.test.cjs

Tests cover state transitions, repeat/acknowledge/mute behavior, disconnections, invalid payloads, web routes, camera controls, credential isolation, and sound initialization. Template XML validation runs separately in unraid-templates. CI builds Linux AMD64 and ARM64 images. To update an UNRAID installation after a new image is published, use Check for Updates on its Docker page.

Updating to version 0.2.16

Images are published as ghcr.io/jbat66/prusa-print-monitor:0.2.16 and :latest. The source release is tagged v0.2.16; VERSION is the application version, also shown in the dashboard header and status API. See CHANGELOG.md.

Existing UNRAID containers retain their old settings. Update the container configuration using the new template: change the container port to 8085 (and host port to 8085 unless you prefer another port), remove ALERT_SOUND_FILE, replace the old single-file mount with a writable Sounds Folder directory at /sounds, and set Sound File to /mnt/user/appdata/prusa-print-monitor/sounds/AlarmSoundEffect.mp3, and set ALERT_REPEAT_SECONDS=60. The camera URL is now unmasked. Update the image and recreate/apply the container.

The existing notice row reports whether alerts, camera, or both are disabled, without adding another row. When both features are enabled, audio readiness or pending alerts use that same notice.

Container stop troubleshooting

Version 0.2.2 handles Docker SIGTERM and stops camera workers cleanly. Update to :0.2.2 or the current :latest. If an older container refuses to stop, use the UNRAID terminal to run docker stop --time 5 Prusa-Print-Monitor (substitute the exact container name). Docker will force-stop it after the timeout if necessary. If it still runs, try docker kill Prusa-Print-Monitor once and save any error text; a failure to force-stop needs Docker/host diagnostics. Then apply the updated image.

Camera diagnostics (0.2.3)

Open the container's Logs screen in UNRAID, then click Enable Camera in the dashboard. Timestamped entries named Prusa-Print-Monitor.log report connection attempts, FFmpeg errors, first video frames, stream endings and timeouts. These entries go to container stdout, which Docker/UNRAID captures; no separate host log-file mapping is required. Printer connection/state changes and shutdown also appear there. Camera URL credentials and the printer API key are redacted.

The dashboard checks the camera session status every two seconds and reports a failure if no complete frame arrives for 15 seconds. Check the log for authentication errors, connection refused, unsupported streams or timeouts. Confirm CAMERA_URL is a camera video stream reachable from UNRAID; for RTSP, use the camera's documented stream path. Click Camera Enabled to stop, then Enable Camera to retry.

Version 0.2.4 fixes the RTSP startup error Option rw_timeout not found. RTSP cameras use the demuxer-specific timeout option; HTTP/HTTPS streams retain rw_timeout. No CAMERA_URL change is required for this fix.

Version 0.2.5 positions the enabled camera beside Printer Status on wide screens in Desktop (up to 360px wide) and Across the Room (up to 640px wide). Compact Corner and Mobile keep the camera below the status/metrics, and narrow screens stack the content. Changing layouts preserves the running camera stream.

Version 0.2.6 alphabetizes the layout menu and shows Acknowledge beside Layout only while a state-change alert is pending. Mobile devices start in Mobile layout on each page load, even if another layout was saved; you can still choose another layout during the session. Full screen is hidden on mobile devices. Desktop browsers retain their saved layout and Full screen control.

Version 0.2.7 places Acknowledge in its own conditional row above Layout. Mute appears only after Enable sounds succeeds. Muting changes the notice to “Sounds muted • Unmute to allow alerts to play”. A simplified favicon is served at /favicon.ico with 16, 24, 32, 48, 64, 128 and 256 pixel entries.

Version 0.2.8 colors the ready-sounds notice green and keeps muted/disabled notices orange. The simplified assets/app-icon.png is used in the web header and UNRAID template; the original large assets/icon.png is retained as the README illustration. Existing UNRAID installations should update the Icon URL to https://raw.githubusercontent.com/jbat66/Prusa-Print-Monitor/main/assets/app-icon.png.

Version 0.2.10 adds a live clock using the viewing device’s local time. Enable sounds silently unlocks Web Audio instead of playing the alarm as a test. Each actual state-change alert uses a fresh playback source, allowing repeat playback until acknowledged. If iOS suspends audio, the dashboard asks you to tap Enable sounds again. Keep the page foreground and the phone awake for dependable alerts; browser/phone background suspension still applies. Audio is decoded once per page session, so refresh after changing the selected sound.

Version 0.2.11 adds camera focus mode: double-click or double-tap the live camera to expand it to the selected layout’s normal full width. The existing header/clock/connection indicator, sound notice, Acknowledge row and footer remain; printer status and timing panels are hidden. Double-click/double-tap again or press Escape to return. Layout changes continue to work without restarting the camera. Enable sounds disappears after success and returns if audio permission needs to be restored.

Version 0.2.13 adds DEFAULT_LAYOUT to the UNRAID template, Compose and .env.example. It selects the initial layout when a non-mobile browser loads the page, taking precedence over an older saved choice. Phones and tablets still start in Mobile regardless of this setting. Users can choose another layout during the page session; polling does not reset that choice. After changing the Docker variable, apply/recreate the container and reload the page. Accepted values are desktop, compact, mobile and large (Across the Room).

Version 0.2.16 retries a failed camera after one minute, then up to three more times at one-minute intervals. A live stream resets the retry count; after four failed attempts the red border remains until you manually retry.

Version 0.2.15 adds a red border around the camera when its stream ends or becomes unavailable. Retrying or receiving live status clears the border.

Version 0.2.14 hides the Next Filament Change card when no change is scheduled (zero or missing countdown). A positive countdown shows the card in its usual position; an elapsed countdown remains visible as Change due until the printer clears or updates it. The remaining-time card fills the available width when the filament card is hidden.

Related apps

Explore more like this

Explore all

Details

Repository
ghcr.io/jbat66/prusa-print-monitor:latest
Last Updated2026-11-02
First Seen2026-11-02

Runtime arguments

Web UI
http://[IP]:[PORT:8085]/
Network
bridge
Shell
sh
Privileged
false
Extra Params
--security-opt=no-new-privileges:true

Template configuration

Printer status URLVariable

REQUIRED: Replace X.X.X.X with your printer IP address. Keep /api/v1/status.

Target
PRINTER_URL
Default
http://X.X.X.X/api/v1/status
Value
http://X.X.X.X/api/v1/status
API userVariable

PrusaLink HTTP Digest username. Default: maker.

Target
API_USER
Default
maker
Value
maker
API keyVariable

REQUIRED: Sign in at connect.prusa3d.com, select your printer, open Settings, then API keys / PrusaLink. Copy the PrusaLink API key (local password), not the separate Prusa Connect cloud API key. If missing, enable PrusaLink and generate/reset its password on the printer under Settings > Network > PrusaLink, then copy it here. Default username: maker; older PrusaLink installations use their configured username/password.

Target
API_KEY
Default
PUT-KEY-HERE
Value
PUT-KEY-HERE
Printer refresh secondsVariable

Seconds between printer polls. Positive integer; default 60.

Target
REFRESH_SECONDS
Default
60
Value
60
Enable alertsVariable

Set true to enable browser alerts. You MUST supply a readable selected MP3 in Sounds Folder; bundled files are installed automatically. Click Enable sounds in each browser.

Target
ALERT
Default
false
Value
false
Enable cameraVariable

Set true to allow camera viewing. You MUST supply your camera stream URL using CAMERA_URL. Toggle the feed in the web interface.

Target
CAMERA
Default
false
Value
false
Camera stream URLVariable

Replace this example with your actual RTSP or HTTP camera stream URL. Used only when CAMERA=true. Credentials stay on the server.

Target
CAMERA_URL
Default
rtsp://x.x.x.x/live
Value
rtsp://x.x.x.x/live
Alert repeat secondsVariable

Repeat unacknowledged alerts at this interval. Positive integer.

Target
ALERT_REPEAT_SECONDS
Default
60
Value
60
Printer request timeoutVariable

Maximum seconds for a printer request. Positive integer.

Target
REQUEST_TIMEOUT_SECONDS
Default
10
Value
10
TimezoneVariable

Container timezone. Estimated finish and last updated are displayed in each browser's local timezone.

Target
TZ
Default
America/Denver
Value
America/Denver
Default LayoutVariable

Initial layout for non-mobile devices: desktop, compact, mobile, or large (Across the room). Phones and tablets always start in Mobile. Manual layout selection remains available. Reload the page after changing this setting.

Target
DEFAULT_LAYOUT
Default
desktop
Value
desktop
Web interface portPorttcp

Host port for the web dashboard. Change if 8085 is already used.

Target
8085
Default
8085
Value
8085
Sounds FolderPathrw

Writable host folder. At startup the four bundled MP3s are copied here only when missing; existing files are preserved. The app uses this folder as /sounds. Change this host folder when storing sounds elsewhere.

Target
/sounds
Default
/mnt/user/appdata/prusa-print-monitor/sounds
Value
/mnt/user/appdata/prusa-print-monitor/sounds
Sound FileVariable

Select the alert MP3 by host path or filename. Default: AlarmSoundEffect.mp3. Other bundled choices: ClockChimes.mp3, Cuckoo.mp3, RedAlert.mp3. The filename is resolved inside Sounds Folder at /sounds; update both entries when moving the folder. Existing files are never overwritten.

Target
SOUND_FILE
Default
/mnt/user/appdata/prusa-print-monitor/sounds/AlarmSoundEffect.mp3
Value
/mnt/user/appdata/prusa-print-monitor/sounds/AlarmSoundEffect.mp3