Eine Kamera am Vogelhaus, ein Rechner der erkennt wer da war — und eine Sammlung, die sich von allein fuellt. Zwei neuronale Netze: eines findet den Vogel im Bild, eines bestimmt die Art. 148 heimische Arten, auf Deutschland eingeschraenkt und neu normiert — ohne diese Einschraenkung wird aus einer Kohlmeise eine nordamerikanische Schwesterart. Daraus entsteht ein Sammelalbum: nummerierte Seiten, gefundene Arten in Farbe, fehlende als Schatten, dazu Erstfang, Punkte, Stufen und 15 Abzeichen. Laeuft vollstaendig auf eigener Hardware. Kein Cloud-Dienst, kein Konto, keine Telemetrie; die Bilder verlassen das eigene Netz nicht. Zwei getrennt deploybare Teile: die Sammlung als Django-Anwendung, die Erkennung als eigener Dienst. Der Erkennungs-Dienst fragt selbst an und braucht deshalb weder eine erreichbare Adresse noch einen offenen Port — er laeuft hinter einem gewoehnlichen Router. Dabei: Firmware fuer Raspberry Pi und ESP32-S3, Anbindung an Home Assistant ueber MQTT, Oberflaeche auf Deutsch und Englisch, Einstellungen je Kamera aus dem Browser, und ein Weg fuer Fotos von unterwegs. AGPL-3.0.
76 lines
2.6 KiB
Desktop File
76 lines
2.6 KiB
Desktop File
#
|
|
# Fotos bestimmen, die über die App oder das Formular hochgeladen wurden.
|
|
#
|
|
# 🔑 **Der Dienst holt sich die Arbeit SELBST ab.** Er fragt die Web-App
|
|
# jede Minute nach offenen Fotos (GET /api/offen/) und meldet das Ergebnis
|
|
# zurück (POST /api/offen/<id>/). Er braucht deshalb weder eine erreichbare
|
|
# Adresse noch einen offenen Port — dieselbe Richtung wie bei der
|
|
# Fernkonfiguration, und aus demselben Grund: Der Erkennungs-Host steht im
|
|
# Heimnetz hinter einem Router, die Web-App nicht.
|
|
#
|
|
# ⚠️ **Ohne diesen Dienst bleibt JEDES App-Foto unbestimmt liegen.** Die App
|
|
# zeigt dann dauerhaft "wird bestimmt …", und zwar ohne Fehler — der Upload
|
|
# war ja erfolgreich. Das sieht nach einem Fehler in der App aus und liegt
|
|
# auf einer anderen Maschine.
|
|
#
|
|
# Gehört auf denselben Host wie die Kamera-Detektoren: Dort liegen die
|
|
# Modelle und das venv schon.
|
|
#
|
|
# cp deploy/vogelalbum-warteschlange.service /etc/systemd/system/
|
|
# # Zugangsdaten anlegen (chmod 600!):
|
|
# cat > /etc/vogelalbum-warteschlange.env <<ENV
|
|
# VOGELALBUM_API=https://<deine-instanz>
|
|
# VOGELALBUM_TOKEN=<Token einer Kamera -- zum Zurueckmelden>
|
|
# VOGELALBUM_LESE_TOKEN=<Lese-Token -- zum Abrufen der offenen Fotos>
|
|
# ENV
|
|
# chmod 600 /etc/vogelalbum-warteschlange.env
|
|
# systemctl enable --now vogelalbum-warteschlange
|
|
#
|
|
# ✅ **Einmal von Hand auslösen, bevor man sich darauf verlässt**: ein Foto
|
|
# hochladen und `journalctl -u vogelalbum-warteschlange -f` mitlesen. Ein
|
|
# Dienst, der sauber läuft und nichts tut, sieht im Status genauso aus wie
|
|
# einer, der arbeitet.
|
|
#
|
|
# 🔑 Zum Prüfen ein Bild OHNE Vogel nehmen. Dann durchläuft es die ganze
|
|
# Kette, aber es entsteht keine Sichtung — ein Testvogel in einer echten
|
|
# Sammlung muss hinterher wieder heraus.
|
|
|
|
[Unit]
|
|
Description=Vogelalbum: Fotos aus der App bestimmen
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=vogelalbum
|
|
Group=vogelalbum
|
|
WorkingDirectory=/opt/vogelalbum
|
|
EnvironmentFile=/etc/vogelalbum-warteschlange.env
|
|
Environment=PYTHONUNBUFFERED=1
|
|
|
|
# --alle 60: Häufiger bringt nichts. Ein gerade hochgeladenes Foto ist beim
|
|
# nächsten Durchgang dran, und die App wartet ohnehin mit wachsenden
|
|
# Abständen auf das Ergebnis.
|
|
ExecStart=/opt/vogelalbum/venv/bin/python -m detector warteschlange --alle 60
|
|
|
|
Restart=always
|
|
RestartSec=15
|
|
|
|
KillSignal=SIGTERM
|
|
TimeoutStopSec=20
|
|
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=true
|
|
ProtectKernelTunables=true
|
|
ProtectControlGroups=true
|
|
RestrictSUIDSGID=true
|
|
ReadWritePaths=/var/lib/vogelalbum
|
|
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|