Files
vogelalbum/web/dex/migrations/0003_camera_sighting_camera.py
christian c11fe9ab04 Vogelalbum 1.0.0
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.
2026-10-15 14:30:02 +00:00

39 lines
1.6 KiB
Python

# Generated by Django 6.1 on 2026-08-28 11:11
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dex', '0002_species_reference_credit_species_reference_image_and_more'),
]
operations = [
migrations.CreateModel(
name='Camera',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=80)),
('slug', models.SlugField(max_length=48, unique=True)),
('location', models.CharField(blank=True, max_length=120, verbose_name='Standort')),
('token_hash', models.CharField(editable=False, max_length=64, unique=True)),
('active', models.BooleanField(default=True, verbose_name='Aktiv')),
('created_at', models.DateTimeField(default=django.utils.timezone.now)),
('last_seen', models.DateTimeField(blank=True, null=True, verbose_name='Zuletzt gemeldet')),
],
options={
'verbose_name': 'Kamera',
'verbose_name_plural': 'Kameras',
'ordering': ['name'],
},
),
migrations.AddField(
model_name='sighting',
name='camera',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sightings', to='dex.camera', verbose_name='Kamera'),
),
]