Charts
3 tools, defined in tools/charts.py.
| Tool | Title | Access |
|---|---|---|
open_charts |
Open Telemetry Dashboard | read-only |
render_charts_html |
Render Dashboard HTML | read-only |
render_charts_panels |
Render Dashboard Panels | read-only |
open_charts
Open Telemetry Dashboard · read-only
Generate and open a responsive telemetry dashboard for the named printer.
WHEN to use: the human user wants to see the printer's rolling telemetry (temperatures, fans, print health, failure drivers) as charts in a browser tab. The dashboard also carries a fixed H2D camera-calibration drawing and an AMS filament panel with the loaded spools' remaining percentage (see Notes).
Sibling disambiguation: render_charts_html returns the same dashboard HTML as a
string and opens nothing; render_charts_panels returns only the SVG panels.
open_job_state opens the background monitor's health images (camera composite,
annotated frame), not these time-series charts. get_monitoring_series returns a URL
to the raw JSON series for one field, which the caller then fetches, rather than a
rendered dashboard.
Parameters
name(string, required): Printer name as configured (case-sensitive; seeget_configured_printers).
Returns
{"output_path": str, "opened": bool} on success. output_path is the static
HTML file /tmp/bambu-charts-{name}.html, written on every call (created readable by its owner
only, an existing file replaced); in the file name "/", "\", "%" and control characters of the
printer name are percent-encoded (so the file always sits directly inside /tmp and two different
names give two different file names) and every other character, spaces and non-ASCII included,
is kept as is. Different file names are not a guarantee of different files: a filesystem that
ignores case or Unicode normalisation (APFS does both) maps names that differ only in case or
normalisation form onto one file. A name that would make the file name longer than 200 bytes
(UTF-8) is cut to fit and gets -<12 hex characters of the name's SHA-256> before .html, so
long names that share a head still get different file names. opened is True
when an existing browser tab was focused or the browser was launched successfully,
False when the browser launch reported failure. Returns {"error": "not_connected"}
when no telemetry collector exists for the printer: collectors are created only for
printers configured when the server started, so a printer added with add_printer
at runtime returns this until the server restarts. A paused or disconnected printer
that has a collector renders its last-collected data instead of an error.
{"error": "unsafe_output_path", "detail": ...} (nothing written, no browser opened) when
the file path resolves outside /tmp or is a symbolic link, which happens only if something else
planted a symlink at that path (the file is opened without following a symlink, so one planted
between the check and the write is refused too).
{"error": "write_failed", "detail": str} (no browser opened) when the file cannot be written
for any other reason (a directory at that path, no permission, a full disk).
Notes
Side effects: writes the HTML file above and focuses or opens a browser tab.
The opened URL is http://localhost:{api_port}/api/charts?printer={name} (the
page then auto-refreshes live data every 30 s) when the API server port is known,
otherwise the static file:// URL of the written file (no live refresh). The name
is percent-encoded in either URL, so a printer name containing a space, "&", "#" or
"+" reaches the server intact; names made only of letters, digits and "-", "_", ".",
"~" appear unchanged.
An existing tab is reused only on macOS, and only when Google Chrome or Safari
already has a tab whose URL starts with the target URL (found with a 3-second
osascript query). On any other platform, or when no such tab exists, a new tab is
opened with webbrowser.open on the machine running the server.
Renders 6 chart sections as inline SVGs assembled into a dark-themed responsive HTML page:
1. Temperature history — two side-by-side panels: nozzle(s), and bed and chamber
together
2. Fan speeds — all 4 fans as a full-width step chart
3. Anomaly signals + print health timeline (side by side)
4. Failure driver spider chart + legend | print state pie
5. Camera calibration corner status — a FIXED reference drawing of the H2D camera
calibration constants with a hardcoded calibration caption; not per-printer, not
telemetry, and identical for every printer including non-H2D models
6. AMS filament remaining bars — one bar per loaded spool from ``get_spool_info``
(slots and holders that hold no filament are skipped), coloured with the spool
colour and labelled with its remaining percentage, or "n/a" when the tray
reports none; shows a "No AMS spool data" placeholder when no spool is loaded or
the spool lookup fails (logged as a warning)
Nozzle panel: when the second extruder (tool_1) has reported a nonzero temperature in the retained window, the panel overlays two lines on one axes, "Right Nozzle" (T0) and "Left Nozzle" (T1), in that legend order, with no spatial left-to-right ordering. That data heuristic, not the printer model, selects the dual layout; otherwise a single "Nozzle" series is shown.
History and resets: temperature, fan and event series cover the last 60 minutes and are held in memory only, so they start empty at server start. The health and anomaly panels hold the most recent 60 analysis records (roughly an hour) and are cleared when the monitor sees a new job start (a change into RUNNING or PAUSE from an idle state). The print-state pie shows time spent in each gcode_state for the current job, including idle time, and resets only when a new job name is seen.
Health timeline and anomaly data come from the background print monitor, which skips camera analysis while the job is in a preparation or maintenance stage (bed leveling, preheating, filament change, calibration, a pause). Records begin on the monitor's first tick (ticks run about every 10 s) after the printer is RUNNING or PAUSE and out of those stages, not 60 s later, and then about every 60 s. Nothing is recorded while the printer is idle, while the job is in one of those stages, when no camera frame can be captured, or when the failure-probability model returns no value.
Failure driver radar: with no analysis result yet, or while the monitor's latest
result is a stage-gated placeholder (neither carries factor_contributions), the
radar renders a placeholder with every factor at 0.5, a uniform polygon that looks
like measured data but is not. Only a radar drawn from a real factor_contributions
result reflects measured risk.
render_charts_html
Render Dashboard HTML · read-only
Render and return the full telemetry dashboard HTML for a printer as a string.
WHEN to use: you need the dashboard page markup itself (this is what the /api/charts
HTTP route serves) without writing a file or opening a browser.
Sibling disambiguation: open_charts renders the same page, writes it to
/tmp/bambu-charts-{name}.html (name made file-safe, see open_charts Returns) and opens it in a
browser; render_charts_panels
returns only the SVG panels as JSON for AJAX refresh instead of the full page.
Parameters
name(string, required): Printer name as configured (case-sensitive; seeget_configured_printers).
Returns
A str containing a complete HTML document (six inline-SVG chart sections plus a
30 s auto-refresh script). The AMS Filament section draws the loaded spools, or a "No
AMS spool data" placeholder when none is loaded; the calibration section is a fixed
H2D reference drawing (see open_charts Notes). The document is VERY LARGE (six inline
SVGs from 16-inch-wide figures carrying up to an hour of plotted points; several
hundred KB is typical, estimated rather than measured), so it suits the
/api/charts HTTP route or a human-facing consumer; an agent should call
open_charts or get_monitoring_series instead of pulling it into context.
This tool never returns a dict: when no telemetry collector exists for the printer
(the printer was not configured when the server started) it returns a short HTML
error page
(<html><body style=...><h2>Printer '<name>' not connected</h2></body></html>)
instead. It writes no file and opens no browser.
Notes
History windows, reset behavior and health-data timing are the same as described in
open_charts Notes.
render_charts_panels
Render Dashboard Panels · read-only
Render only the telemetry dashboard SVG panels for a printer, for AJAX refresh.
WHEN to use: refreshing the dashboard charts in place (this is what the
/api/charts_panels HTTP route serves and what the dashboard page polls every 30 s),
when you do not need the surrounding HTML page.
Sibling disambiguation: render_charts_html returns the whole dashboard page as an
HTML string; open_charts writes that page to a file and opens it in a browser. This
tool returns only the six chart SVGs plus a timestamp.
Parameters
name(string, required): Printer name as configured (case-sensitive; seeget_configured_printers).
Returns
{"panels": [svg, ...], "ts": "YYYY-MM-DD HH:MM:SS"} on success. panels holds
six inline SVG strings in dashboard order: temperatures, fans, anomaly and health,
failure analysis, camera calibration (a fixed H2D reference drawing), AMS filament.
panels[5] draws the loaded spools, or the "No AMS spool data" placeholder SVG when
none is loaded. The payload is
VERY LARGE (six inline SVG strings; several hundred KB is typical, estimated rather
than measured). It exists for the dashboard page's own AJAX refresh via
/api/charts_panels; an agent should use open_charts or
get_monitoring_series instead of pulling it into context. Returns
{"error": "Printer '<name>' not connected"} when no telemetry collector exists
for the printer, i.e. it was not configured when the server started (note the
message text differs from open_charts, which returns
{"error": "not_connected"}).
Notes
History windows, reset behavior and health-data timing are the same as described in
open_charts Notes.