144 lines
5.5 KiB
Markdown
144 lines
5.5 KiB
Markdown
<p align="center">
|
||
<img src="docs/brand/readme-banner.png" alt="Grotti" width="720">
|
||
</p>
|
||
|
||
<p align="center">
|
||
<strong>Farm-Manager für Moonraker-Drucker</strong><br>
|
||
Eine Oberfläche für die ganze Farm: Wand, Warteschlange, Material, Abläufe und Protokoll.<br>
|
||
<em>Benannt nach der Mühle Grotti — sie mahlt ohne Pause, was man ihr aufträgt.</em>
|
||
</p>
|
||
|
||
<p align="center">
|
||
<a href="https://git.gundel.dev/dg/grotti"><img src="https://img.shields.io/badge/Version-3.4.0-e85d04?style=flat-square" alt="Version 3.4.0"></a>
|
||
<img src="https://img.shields.io/badge/Python-3.11+-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python 3.11+">
|
||
<img src="https://img.shields.io/badge/PostgreSQL-14+-4169E1?style=flat-square&logo=postgresql&logoColor=white" alt="PostgreSQL">
|
||
<img src="https://img.shields.io/badge/Moonraker-Klipper-2ecc71?style=flat-square" alt="Moonraker">
|
||
<img src="https://img.shields.io/badge/UI-Deutsch-111827?style=flat-square" alt="UI Deutsch">
|
||
<img src="https://img.shields.io/badge/Self--hosted-lokal-6b7280?style=flat-square" alt="Self-hosted">
|
||
</p>
|
||
|
||
<p align="center">
|
||
<a href="#features">Features</a> ·
|
||
<a href="#screenshots">Screenshots</a> ·
|
||
<a href="#schnellstart">Schnellstart</a> ·
|
||
<a href="#api">API</a> ·
|
||
<a href="CHANGELOG.md">Changelog</a> ·
|
||
<a href="docs/community/README.md">Community</a>
|
||
</p>
|
||
|
||
---
|
||
|
||
<p align="center">
|
||
<img src="docs/community/01-druckerwand.png" alt="Druckerwand" width="900">
|
||
</p>
|
||
|
||
## Features
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| **Druckerwand & Cockpit** | Live-Status, Temps, Pause/Cancel, Farm-ETA |
|
||
| **Warteschlange** | Priorität, „nächster freier“, Material-Match, ACE-Map |
|
||
| **Dateien & Projekte** | Slice-Watch, Senden, Umbenennen, Projektordner |
|
||
| **Kobra-3-Ablauf** | Druck → Abkühlen → Schieben → Tasten |
|
||
| **Material** | Spulen, Restgewicht, Bedarf, Chargen |
|
||
| **Aufträge & Statistik** | Kunden, Lieferschein, Kosten (€ Material+Strom) |
|
||
| **Betrieb** | Auth (Session/`grt_…`), Telegram/ntfy, PWA |
|
||
|
||
Stack: **Python · Flask · PostgreSQL · Moonraker** (Rinkhals auf Kobra 3 / S1).
|
||
|
||
## Screenshots
|
||
|
||
<p align="center">
|
||
<img src="docs/community/06-jetzt.png" alt="Jetzt-Liste" width="440">
|
||
|
||
<img src="docs/community/02-warteschlange.png" alt="Warteschlange" width="440">
|
||
</p>
|
||
<p align="center">
|
||
<img src="docs/community/09-dateien.png" alt="Dateien" width="440">
|
||
|
||
<img src="docs/community/03-material.png" alt="Material" width="440">
|
||
</p>
|
||
<p align="center">
|
||
<img src="docs/community/05-statistik.png" alt="Statistik" width="440">
|
||
|
||
<img src="docs/community/07-cockpit.png" alt="Cockpit" width="440">
|
||
</p>
|
||
|
||
Weitere Bilder und Post-Text: [`docs/community/`](docs/community/README.md).
|
||
|
||
## Schnellstart
|
||
|
||
**Voraussetzungen:** Python 3.11, PostgreSQL (leere DB `grotti`), Drucker mit Moonraker im LAN.
|
||
|
||
```powershell
|
||
cd D:\Projekte\Grotti
|
||
python -m venv .venv
|
||
.\.venv\Scripts\pip install -r requirements.txt
|
||
copy config.example.json config.json
|
||
.\.venv\Scripts\python.exe server.py
|
||
```
|
||
|
||
Dann <http://127.0.0.1:8770/>. Bedienung unter **Doku** in der App (`docs/Anleitung-*.md`).
|
||
|
||
`config.json` und `data/` bleiben lokal (nicht im Git). Drucker zuerst in `drucker.json`, danach unter Einstellungen.
|
||
|
||
| Schlüssel | Bedeutung |
|
||
| --- | --- |
|
||
| `host`, `port` | Oberfläche (Standard `127.0.0.1:8770`) |
|
||
| `database_url` | PostgreSQL |
|
||
| `watch_dir` | Slice-Ordner (oder leer = nur Upload) |
|
||
| `energy` / `telegram` / `alerts` | Kosten und Benachrichtigungen |
|
||
|
||
Schema-Migrationen laufen beim Start (`grotti/migrations/`). Vor Major-Updates: `pg_dump`.
|
||
|
||
## Ordner
|
||
|
||
| Pfad | Inhalt |
|
||
| --- | --- |
|
||
| `server.py` | Start, DB, Hintergrund-Threads |
|
||
| `grotti/` | Moonraker, Queue, Senden, Abräumen, Watcher, Store |
|
||
| `web/` | Flask, Templates, CSS/JS, Branding |
|
||
| `docs/` | Anleitungen (`/doku`), Community-Screens, Technik unter `internal/` |
|
||
| `CHANGELOG.md` | Versionen |
|
||
|
||
## API
|
||
|
||
Alles unter `/api/v1`, JSON. Auth: Session oder `Authorization: Bearer grt_…`.
|
||
|
||
| Methode und Pfad | Zweck |
|
||
| --- | --- |
|
||
| `POST /auth/setup`, `/auth/login`, `/auth/logout` | Ersten Admin, Login, Logout |
|
||
| `GET /me`, `/users`, `/tokens` | Konto, Benutzer (Admin), API-Tokens |
|
||
| `GET /version` | Version |
|
||
| `GET`/`PATCH /einstellungen`, `POST /telegram/test` | Config und Telegram-Probe |
|
||
| `GET /drucker?live=1` | Drucker mit Live-Zustand |
|
||
| `POST /drucker/<host>/<aktion>` | Pause, Fortsetzen, Abbrechen, Fehler löschen |
|
||
| `POST /drucker/<host>/steuern` | Temperatur, Speed, Flow, Lüfter, ACE |
|
||
| `POST /drucker/<host>/abraeumen` | Platte geräumt (`confirm`) |
|
||
| `GET`/`POST /dateien`, `PATCH`/`DELETE /dateien/<id>` | Bibliothek |
|
||
| `POST /senden`, `GET`/`POST /druck-queue` | Senden und Warteschlange (`confirm`) |
|
||
| `GET /spulen`, `POST /spulen/<id>/einlegen` | Material |
|
||
| `GET /laeufe`, `/statistik`, `/ereignisse` | Protokoll und Aktivität |
|
||
|
||
MCP: `python -m grotti.mcp_server` mit `GROTTI_URL` / `GROTTI_TOKEN` → `docs/internal/MCP.md`.
|
||
|
||
## Sicherheit
|
||
|
||
- Login Pflicht. Rollen: Admin, Operator.
|
||
- Druckstarts brauchen `confirm: true` (Zwei-Klick in der UI).
|
||
- Keine freie G-code-Konsole; kein `FIRMWARE_RESTART` über Grotti.
|
||
- Nach außen: Reverse Proxy mit TLS.
|
||
|
||
## Versionen
|
||
|
||
- SemVer in `grotti/version.py`, Einträge in [CHANGELOG.md](CHANGELOG.md).
|
||
- Release: `[Unreleased]` → `[x.y.z] – Datum`, Tag `vX.Y.Z`.
|
||
- CSS/JS-Cache: `?v=` in `layout.html` mitziehen.
|
||
|
||
---
|
||
|
||
<p align="center">
|
||
<img src="web/static/brand/logo.png" alt="" width="72"><br>
|
||
<sub>Repo: <a href="https://git.gundel.dev/dg/grotti">git.gundel.dev/dg/grotti</a></sub>
|
||
</p>
|