Skip to content

Repository files navigation

Sentry3D

Sentry3D is a local-first Home Assistant integration that watches a 3D-printer camera, asks a vision model running in Ollama to assess the current print, and turns repeated high-confidence failures into durable Home Assistant incidents. It is designed for Home Assistant users who want useful print-failure alerts without sending camera frames or credentials to a cloud model.

What it does

  • Reads snapshots from an existing Home Assistant camera entity, or captures an RTSP/RTSPS stream with FFmpeg.
  • Keeps a three-frame temporal window so the model can distinguish a developing failure from a single ambiguous image.
  • Uses motion and printer-state awareness to avoid needless inference while still running periodic heartbeat analyses.
  • Calls only a private or loopback Ollama endpoint. Cloud model tags and public inference endpoints are rejected.
  • Requests a strict structured observation from Ollama, then applies incident thresholds in deterministic Python code.
  • Preserves the last trustworthy status when capture, transport, or model parsing fails. Runtime errors never create or clear incidents.
  • Exposes Home Assistant entities, events, persistent notifications, bounded history, and a status-first dashboard card.

Sentry3D never needs an API key. It does not install or operate Ollama for you.

Requirements

  • Home Assistant 2025.12.0 or newer.
  • Ollama reachable from the Home Assistant host on a loopback, private, link-local, or private DNS address. The default Qwen3-VL model requires Ollama 0.12.7 or newer.
  • A vision-capable Ollama model. The default is configurable and currently qwen3-vl:4b.
  • One Home Assistant camera entity, or an RTSP/RTSPS camera URL. Direct RTSP capture also requires FFmpeg in the Home Assistant runtime.

Install the default model on the Ollama host:

ollama pull qwen3-vl:4b

For best results, start with a clear, fixed camera view that includes the nozzle, printed part, and most of the build plate.

Installation

HACS custom repository

  1. Add this repository to HACS as an Integration repository.
  2. Install Sentry3D.
  3. Restart Home Assistant.

Manual

Copy custom_components/sentry3d into the custom_components directory in your Home Assistant configuration, then restart Home Assistant.

Setup

  1. In Home Assistant, open Settings → Devices & services → Add integration.
  2. Search for Sentry3D.
  3. Select a Home Assistant camera entity or enter an RTSP/RTSPS URL.
  4. Optionally select the printer's state entity. States such as printing, running, busy, and paused are treated as active; a known inactive state suppresses automatic analysis.
  5. Enter the local Ollama URL and installed model name. Setup verifies both before creating the entry.
  6. Review the analysis and incident policy settings.

The default settings capture every 5 seconds, run a heartbeat analysis at least every 30 seconds, require two consecutive unhealthy observations at confidence 0.85 or above, and rate-limit repeat notifications to five minutes. Motion immediately triggers analysis, and a pending failure confirmation bypasses motion gating.

All settings remain editable from the integration's options flow. No secrets are stored because Ollama authentication and cloud providers are not supported.

Dashboard card

The integration serves the bundled card at /sentry3d/sentry3d-card.js. Add that URL as a JavaScript module under Settings → Dashboards → Resources, then add a manual card:

type: custom:sentry3d-card
entity: sensor.sentry3d_status

The card discovers the other entities belonging to the same config entry. It shows the current assessment, latest analyzed camera frame, monitoring and Ollama health, recent observations, an Analyze now action, and a monitoring toggle.

Home Assistant contract

Existing entity unique IDs, Store keys, events, and service names are retained across the 1.0 migration.

Entities created for each entry:

  • sensor.*_status, sensor.*_confidence, sensor.*_reason, and sensor.*_short_explanation
  • binary_sensor.*_unhealthy, binary_sensor.*_incident_active, binary_sensor.*_motion_detected, and binary_sensor.*_ollama_reachable
  • camera.*_last_frame
  • button.*_force_update
  • switch.*_monitoring

The exact entity IDs can differ when Home Assistant resolves name collisions. Automations should prefer the integration-created entities or their stable unique IDs.

Sentry3D fires sentry3d_incident when a new incident opens. Its payload includes the entry ID, integration name, status, confidence, reason, timestamp, signals, incident ID, defect, and severity. Fresh qualifying evidence can also create a rate-limited persistent notification.

The existing sentry3d.pause_print and sentry3d.cancel_print services remain compatibility stubs: they do not control printer hardware and fire sentry3d_control_stub instead. Observation history is available to the bundled card through the authenticated sentry3d/history Home Assistant WebSocket command, with a maximum request size of 100 records.

Status and incident semantics

The model returns a structured observation containing scene, health, defect type, severity, visibility, confidence, evidence, and optional normalized image regions. Sentry3D maps that richer result to the stable public states HEALTHY, UNHEALTHY, EMPTY, and UNKNOWN.

Only a fresh UNHEALTHY result at or above the configured confidence threshold advances the unhealthy counter. HEALTHY and EMPTY reset the counter and clear an active incident. UNKNOWN, capture failures, Ollama failures, and invalid model responses leave the incident state unchanged. This prevents infrastructure problems from looking like printer failures or recoveries.

Architecture

HA camera snapshot or RTSP/FFmpeg
              │
              ▼
      frame preprocessing
  (JPEG normalization + motion)
              │
              ▼
   temporal monitoring engine ───── printer state
              │
              ▼
      local Ollama /api/chat
   (images + strict JSON schema)
              │
              ▼
 deterministic incident policy
              │
       ┌──────┼─────────┐
       ▼      ▼         ▼
  HA entities events  Store v1
       │                schema v2 payload
       ▼
  Lit dashboard card + bounded WebSocket history

The Home Assistant coordinator handles scheduling and I/O. The monitoring engine owns temporal context, and the policy module owns incident transitions. Ollama transport, prompting/schema, image handling, and Home Assistant presentation are separated so the safety-critical policy can be unit tested without Home Assistant or a live model.

Upgrading an older entry migrates its provider to Ollama and removes legacy OpenAI URL, model, and API-key fields. Existing history uses the same Home Assistant Store version and key; legacy payloads are read and rewritten as schema version 2. Camera credentials are redacted from diagnostics.

Troubleshooting

Setup cannot reach Ollama

  • From the Home Assistant host, verify http://<ollama-host>:11434/api/tags is reachable.
  • Confirm the hostname resolves only to private, loopback, or link-local addresses.
  • Confirm the configured model appears in ollama list.
  • Do not use an Ollama cloud model tag; Sentry3D intentionally rejects it.

No new analyses

  • Confirm the Monitoring switch is on.
  • Check whether the optional printer-state entity is reporting an inactive state.
  • Inspect Motion Detected, Ollama Reachable, skip_reason, and runtime_error on the Status entity.
  • Use Analyze now to bypass motion, printer-state, and normal scheduling gates once.

RTSP capture fails

  • Prefer an existing Home Assistant camera entity when one is available.
  • Test the RTSP URL from the Home Assistant host and confirm FFmpeg is installed.
  • The direct capture path uses TCP transport for reliability.

Development

Python checks:

python -m pip install -r requirements_test.txt
ruff check custom_components tests
pytest -q
python -m compileall -q custom_components tests

Dashboard checks:

cd frontend
pnpm install --frozen-lockfile
pnpm test
pnpm build

pnpm build writes the production module to custom_components/sentry3d/frontend/sentry3d-card.js; commit the source and rebuilt module together.

License

Apache-2.0

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages