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.
75 lines
2.5 KiB
HTML
75 lines
2.5 KiB
HTML
{% extends "dex/base.html" %}
|
|
{% load i18n dex_extras %}
|
|
|
|
{% block title %}{% trans "Abzeichen" %} — Vogelalbum{% endblock %}
|
|
|
|
{% block kopf %}
|
|
<style>
|
|
/* ⚠ Eigene Klassen statt der xp-track vom Kopfbereich: Die ist dort
|
|
breit und hoch, hier soll der Balken in eine Abzeichenkarte passen
|
|
ohne sie auseinanderzuziehen. */
|
|
.fortschritt {
|
|
margin-top: 8px;
|
|
height: 6px;
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--text) 12%, transparent);
|
|
overflow: hidden;
|
|
}
|
|
.fortschritt-fuellung {
|
|
height: 100%;
|
|
border-radius: 999px;
|
|
background: var(--accent);
|
|
/* Auch bei 0 % ein Hauch sichtbar -- sonst sieht die Karte aus,
|
|
als fehlte der Balken. */
|
|
min-width: 3px;
|
|
}
|
|
.fortschritt-text {
|
|
margin-top: 4px;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
/* Die Karte ist abgeblendet, solange das Abzeichen fehlt. Der Balken
|
|
soll trotzdem lesbar bleiben -- er ist ja der Grund hinzuschauen. */
|
|
.badge.locked .fortschritt-fuellung { opacity: .85; }
|
|
</style>
|
|
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
|
|
<h2>{% trans "Abzeichen" %} <span class="count">{% blocktrans with n=progress.badges %}{{ n }} verdient{% endblocktrans %}</span></h2>
|
|
|
|
<div class="badges">
|
|
{% for row in rows %}
|
|
<div class="badge {% if not row.earned %}locked{% endif %}">
|
|
{% abzeichen_bild row.badge.code as pin %}
|
|
{% if pin %}
|
|
<img class="em" src="{{ pin }}" alt="" width="72" height="72" loading="lazy">
|
|
{% else %}
|
|
<div class="em">{{ row.badge.emoji }}</div>
|
|
{% endif %}
|
|
<div>
|
|
<div class="n">{{ row.badge.name_lokal }}</div>
|
|
<div class="d">{{ row.badge.description_lokal }}</div>
|
|
<div class="d" style="margin-top:6px; color:var(--accent-dim); font-weight:700">
|
|
{% if row.earned %}{{ row.at|date:"SHORT_DATE_FORMAT" }} · +{{ row.badge.xp }} XP{% else %}+{{ row.badge.xp }} XP{% endif %}
|
|
</div>
|
|
|
|
{% comment %}
|
|
🔑 Balken nur, wo es etwas zu zaehlen gibt. Bei "Ein Specht war da"
|
|
stuende er dauerhaft auf null und waere keine Information.
|
|
⚠️ {# … #} ist in Django EINZEILIG — mehrzeilig braucht es comment,
|
|
sonst steht der Text sichtbar auf der Seite.
|
|
{% endcomment %}
|
|
{% if row.ziel %}
|
|
<div class="fortschritt" title="{{ row.ist }} von {{ row.ziel }}">
|
|
<div class="fortschritt-fuellung" style="width: {{ row.anteil }}%"></div>
|
|
</div>
|
|
<div class="d fortschritt-text">{{ row.ist }} / {{ row.ziel }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{% endblock %}
|