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.
55 lines
2.0 KiB
Docker
55 lines
2.0 KiB
Docker
# Nur die Web-App. Der Detector läuft auf dem Host, wo die Rechenleistung ist
|
|
# und wo die Kamera im selben Netz hängt — er gehört nicht in diesen Container.
|
|
FROM python:3.13-slim
|
|
|
|
WORKDIR /app
|
|
|
|
# gettext fuer 'compilemessages' weiter unten. Die .mo-Dateien sind
|
|
# Bauartefakte und liegen nicht im Repo; ohne diesen Schritt fiele die
|
|
# englische Fassung stillschweigend auf die deutschen Texte zurueck.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends gettext \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY requirements-web.txt .
|
|
RUN pip install --no-cache-dir -r requirements-web.txt
|
|
|
|
COPY web/ ./
|
|
# Der Artenkatalog wird von 'seed_dex' importiert.
|
|
#
|
|
# 🔴 Hier stand bis zum 09.10.2026 nur species_de.py — und damit hat jede
|
|
# frisch aufgesetzte Instanz **44 Arten ohne Steckbriefe** bekommen statt der
|
|
# 148, die README und Oberfläche nennen. seed_dex meldete das sogar
|
|
# ("Keine Steckbriefe gefunden"), nur hat es nie jemand gelesen: Die laufende
|
|
# Instanz wurde beim Umzug 1:1 kopiert und nie aus diesem Image geseedet.
|
|
#
|
|
# 🔑 Deshalb kommen alle fünf Datenquellen mit, in derselben Reihenfolge, in
|
|
# der seed_dex sie sucht:
|
|
# species_de.py 44 heimische Gartenvögel, dazu die Seltenheitsstufen
|
|
# species_extra.py der Rest auf 148
|
|
# species_info.py Steckbriefe
|
|
# species_info_en.py dieselben auf Englisch
|
|
# profiles/ die ausführlichen Zusätze
|
|
#
|
|
# Nach wie vor NICHT der ganze Detector: Alles hier ist reine Stdlib
|
|
# (dataclasses), zusammen 280 KB. classify.py und Konsorten bräuchten numpy
|
|
# und LiteRT und haben in diesem Bild nichts verloren.
|
|
COPY detector/__init__.py \
|
|
detector/species_de.py \
|
|
detector/species_extra.py \
|
|
detector/species_info.py \
|
|
detector/species_info_en.py \
|
|
/app/detector/
|
|
COPY detector/profiles/ /app/detector/profiles/
|
|
|
|
# Uebersetzungen binaer erzeugen. Zur Bauzeit, nicht beim Start: sie aendern
|
|
# sich nur mit dem Code.
|
|
RUN python manage.py compilemessages
|
|
|
|
COPY entrypoint.sh .
|
|
RUN chmod +x entrypoint.sh
|
|
|
|
EXPOSE 8000
|
|
|
|
CMD ["./entrypoint.sh"]
|