EMSN

Type minstens twee letters. Resultaten verschijnen vanzelf, geen Enter nodig.

EN
Terug naar de homepage
§ T-01 · Techniek
Onder de motorkap

Vier Pi's, een Synology
en een paar duizend regels code.

Een rondleiding langs wat er waar staat en waarom. De Raspberry Pi's in de bomen, de NAS in de berging, de modellen die soorten herkennen, de leidingen die alles aan elkaar knopen. Niet alles werkte meteen. Onder elke streep zit een verhaal.

§ T-02 · In één plaatje Van zingende merel tot deze website

Zeven stappen tussen de vogel en het scherm.

Een merel zingt, een microfoon pikt het op, aangesloten op een Raspberry Pi met BirdNET, de NAS in huis, een Cloudflare-tunnel en dan pas komt deze site. Hieronder de detailuitleg per onderdeel.

Infographic: van zingende merel via microfoon, Raspberry Pi, AI-detectie en NAS naar deze website.
§ T-03 · De Pi-fleet Welke computer doet wat

Vier Pi's en een Synology.

Elke Pi heeft één taak. De NAS is de spin in het web. Postgres voor de data, Grafana voor de dashboards, een tunnel naar buiten. Mobiel staat los: dat draait op een batterij in het veld.

  • emsn2-zolder

    192.168.x.x

    Hoofdstation: BirdNET-Pi + MQTT-broker + reports-API

    Hardware
    Raspberry Pi 5 (Rev 1.1)
    RAM
    8 GB
    OS
    Debian 13 trixie
    Sensoren
    Stereo USB-mic (Noord/Zuid 7m basislijn)
    ~262 detecties / uur
  • emsn2-berging

    192.168.x.x

    BirdNET-Pi + AtmosBird hemelcam + MQTT-bridge

    Hardware
    Raspberry Pi 5 (Rev 1.1)
    RAM
    8 GB
    OS
    Debian 13 trixie
    Sensoren
    USB-mic mono + HQ Camera IMX477 + M12 2.7mm F2.5
    ~307 detecties / uur
  • emsn2-meteo

    192.168.x.x

    Weergateway naar Davis Vantage Pro2

    Hardware
    Raspberry Pi Zero 2 W
    RAM
    512 MB
    OS
    Debian 12 bookworm
    Sensoren
    Davis console: wind, temp, regen, vocht, druk, UV
    ~57 metingen / uur
  • emsn-sonar

    192.168.x.x

    Vleermuis-detectie, dual stack

    Hardware
    Raspberry Pi 4B (Rev 1.5)
    RAM
    8 GB
    OS
    Debian 13 trixie
    Sensoren
    Dodotronic Ultramic 200kHz (ultrasoon)
    24 vleermuissoorten in archief
  • emsn-mobiel

    192.168.x.x

    Veldstation (apart project, batterij)

    Hardware
    Raspberry Pi 5 + Witty Pi 5
    RAM
    8 GB
    OS
    Debian 13
    Sensoren
    USB-mic + GPS (UART /dev/serial0)
    75 soorten uit veldsessies
  • NAS DS224+

    192.168.x.x

    PostgreSQL + Grafana + go2rtc + USB-archief

    Hardware
    Synology DS224+
    RAM
    OS
    DSM
    Sensoren
    4.0 TB van 7.3 TB gebruikt
§ T · Machines Live · bijgewerkt 04:06:47

De vloot, ademend.

Zes machines werken hier samen. Eén NAS in de berging als data-haard, vier Pi's met sensoren in de tuin, en een mobiel veldstation. Per machine hieronder: temperatuur, geheugen, opslag, en hoe lang ze al achter elkaar aan staan.

  • Bladerdak

    BirdNET stereo (kanaal noord + zuid) + MQTT broker

    CPU
    30%
    RAM
    32%
    Disk
    12%
    Temp 52.1 °C Uptime 4.6d
  • Struikgewas

    AtmosBird hemelcamera

    CPU
    10%
    RAM
    32%
    Disk
    88%
    Temp 51.0 °C Uptime 25.6d
  • Sonar

    BatDetect2 ultrasoon

    CPU
    63%
    RAM
    15%
    Disk
    33%
    Temp 51.1 °C Uptime 12.4d
  • Meteo

    Davis VP2

    CPU
    250%
    RAM
    51%
    Disk
    25%
    Temp 66.1 °C Uptime 8.6d
  • NAS

    Postgres, opslag, mail, web

    CPU
    RAM
    Disk
    Temp Uptime 5.6d
  • Mobiel

    expeditie-station (soms offline)

    CPU
    RAM
    Disk
    Temp Uptime
§ T-04 · Pipelines Hoe een meting van sensor naar database komt

Zes data-stromen, één database.

Elke stroom heeft een eigen pad: andere sensor, ander verwerkings-script, eigen tussen-buffer. Maar ze komen allemaal samen in dezelfde PostgreSQL op de NAS.

01

Weer

318.835 records · 297 dagen
Davis Vantage Pro2 (radio)
    │
    ▼
Davis console, USB serial
    │
    ▼
Pi Meteo: davis-weather-monitor.service
    │
    ▼
MQTT publish emsn2/meteo/weather/*
    │
    ▼
Mosquitto broker op Zolder
    │
    ▼
weather_ingest service
    │
    ▼
▶ PostgreSQL.weather_data

De buiten-sensoren sturen elke minuut via radio naar de Davis-console. Een Pi Zero leest die console uit via USB, publiceert op MQTT, en de NAS schrijft het weg.

02

Akoestiek (vogels)

1.901.302 records · 234 dagen
USB-microfoon (48 kHz)
    │
    ▼
BirdNET-Pi: rolling 15-sec buffer + analyzer
    │
    ▼
Lokale SQLite + MP3-knip + spectrogram
    │
    ▼
lifetime_sync.py (event-driven)
    │
    ▼
PostgreSQL.bird_detections
    │
    ▼
unified-enricher: vocalisatie-CNN + richting
    │
    ▼
▶ NAS USB-archief (159 GB audio)

Elke microfoon hoort 24/7 mee. BirdNET-Pi op de Pi zelf herkent de soort, schrijft een knipje weg, en daarna verrijkt een eigen CNN de vocalisatie en de richting (alleen Zolder, stereo).

03

Vleermuizen

76.350 records · 106 dagen
Dodotronic Ultramic (192 kHz)
    │
    ▼
sonar-bavaria.service: dual stack
    │
    ▼
├─ BatDetect2 (PyTorch, UK-getraind)
    │
    ▼
└─ BattyBirdNET-Bavaria (TF Lite, DE/NL)
    │
    ▼
Ensemble-merge: beide opslaan
    │
    ▼
sonar-monitor.service via MQTT
    │
    ▼
▶ PostgreSQL.bat_detections

Twee detectors draaien parallel omdat ze elkaar aanvullen. BatDetect2 is goed op UK-soorten, Bavaria op centraal-Europese. We dwingen ze niet één antwoord te kiezen.

04

Nestkasten

348.609 records · 206 dagen
3× Tuya nestkast-cam
    │
    ▼
Tuya cloud (protect-eu.ismartlife.me)
    │
    ▼
go2rtc: pull RTSP, herpubliceer WebRTC
    │
    ▼
Auto-screenshot 6× per dag (ook nacht)
    │
    ▼
Pi Zolder reports-api → POST nestbox_media
    │
    ▼
PostgreSQL.nestbox_media + .nestbox_events
    │
    ▼
▶ NAS USB-archief + dashboard

Goedkope Chinese cams zonder open API. Een open-source streaming-gateway (go2rtc) logt in op de Tuya-cloud en publiceert lokaal door. Daarmee komt elk frame in een database in plaats van in een app.

05

AtmosBird hemelcam

28.108 records · 217 dagen
HQ Camera IMX477 + M12 wide-angle
    │
    ▼
atmosbird-stream-relay: MJPEG broker :8889
    │
    ▼
atmosbird-capture.timer: elke 10 min
    │
    ▼
atmosbird-analysis.timer: elke 15 min
    │
    ▼
   ONNX cloud-classifier + ISS + maan + meteor
    │
    ▼
atmosbird-archive-sync.timer: elk uur
    │
    ▼
▶ PostgreSQL.sky_observations + USB

De hemel-camera schiet elke 10 minuten omhoog, een eigen-getrainde classifier zegt of het bewolkt is, en daarnaast schuift hetzelfde script door alle frames op zoek naar ISS-passages, maanstand en meteoren.

06

FlySafe-radar

4.207 records · 217 dagen
KNMI BirdTAM (PNG, geen API)
    │
    ▼
HTTP fetch elke 30 min
    │
    ▼
flysafe-radar: color-analyzer
    │
    ▼
Pixel-classificatie naar 5 levels
    │
    ▼
Extractie rond EMSN-coördinaten
    │
    ▼
correlation_service: tijds-match met detecties
    │
    ▼
▶ PostgreSQL.radar_observations

KNMI publiceert vogeltrek alleen als PNG-kaart, geen download-API. Een eigen color-analyzer leest de paletkleuren uit en zet ze om naar een intensiteit-cijfer per regio.

§ T-05 · Software-stack Wat we gebruiken en waarom

Geen held-software, alleen keuzes met een reden.

Elk onderdeel doet één ding. Veel ervan is open source. Anderen hebben de zware machine learning al gebouwd en getraind, ik koppel het aan elkaar en train zelf alleen waar het nodig is.

Detectie & classificatie

  • Defacto standaard voor edge-vogel-detectie, native SQLite + MP3-export, lage CPU op Pi 5.

  • State-of-the-art voor vleermuis-spectrogrammen, getraind op grote UK-dataset.

  • Beter op centraal-Europese soorten dan BatDetect2. Daarom dual-stack.

  • Generieke classifiers herkennen wel de soort maar niet wát de vogel doet (zang, roep, alarm). Drie generaties modellen, flagship is "ultimate": 4 conv blocks, 256 filters, 35 MB per soort.

  • MobileNetV2 nestkast-classifier

    Lichtgewicht, draait op Pi, transfer learning vanaf ImageNet is voldoende voor "leeg / bezet / eieren". In ontwikkeling.

  • FlySafe BirdTAM color-analyzer

    KNMI levert alleen PNG, geen API. Pixel-classificatie maakt er weer cijfers van.

Infrastructuur

  • Eén centrale waarheid. SQLite per Pi schaalt niet voor cross-station queries.

  • Lichtgewicht message bus, bridge-pattern werkt al jaren tussen de Pi's. Sinds kort ook mTLS op poort 8883.

  • Eén abstractie over Tuya, RTSP en WebRTC. Browser-rendering zonder plugins.

  • Visualisatie en alerts, PostgreSQL als native data-source.

  • Centrale logs van alle Pi's. Voorkomt dat ik in vier hosts moet SSH'en om iets te debuggen.

  • Secrets management. De huidige .secrets-bestanden zijn een tijdelijke patch.

  • systemd timers + services

    Geen cron, geen Docker-overhead op Pi's. Native, met WatchdogSec voor freezes.

  • UPS, RTC, scheduled power-on voor batterij-veldsessies.

Cloud & archief

  • Cloudflare Tunnel

    Ziggo blokkeert poort 80/443 inkomend. Cloudflare maakt een uitgaande tunnel naar hun edge. Geen port-forwards, auto-TLS, auto-DNS.

  • Hosting voor deze site. Auto-deploy bij git-push, gratis voor hobby-projecten.

  • HiDrive (Strato)

    Off-site backup van DB en Pi's via SSH-key. Geen API-key, dus geen vendor-lock.

  • NAS USB 8 TB

    Primair archief. 1 Gbit thuis is sneller dan cloud, en het kost niets per TB.

§ T-06 · Wat er fout ging Vier verhalen die je moet kennen

Stille bugs, harde lessen.

Niets werkt meteen. Maar de ergste fouten zijn niet de crashes. Het zijn de pipelines die wél lijken te draaien maar verkeerde data wegschrijven. Vier voorbeelden.

  1. 01

    De stille bias van de hemel-classifier

    Twee maanden lang gaf de AtmosBird hemel-classifier elke 15 minuten "99% bewolking" terug. Geen exception, geen alert. Oorzaak: `onnxruntime` was uit het venv gevallen, en de fallback-heuristic retourneerde altijd bijna-volledige bewolking. Sindsdien controleren post-deploy smoke-tests specifiek of het echte model laadt.

  2. 02

    Eén verkeerde timer = 200.000 foute records

    De `lifetime-sync-berging.timer` bleek per ongeluk op de Zolder-Pi te draaien. Het script sync'de de Zolder-SQLite eenmaal als zolder en eenmaal als berging: 201.224 records met de verkeerde stations-tag. De fix: hostname-check in het script zelf, en een single-source-of-truth lijst van "welke service hoort op welke host".

  3. 03

    Numba en de ProtectHome-trap

    De audio-library librosa gebruikt numba voor JIT-compilatie en wil cachen onder `~/.cache/numba/`. Maar veilige systemd-services hebben `ProtectHome=read-only`. Resultaat: numba valt stil terug op pure-Python. 50× trager, alleen zichtbaar in debug-logs. Negen dagen lang werd er niet geclassificeerd voor we dat doorhadden.

  4. 04

    Tuya-cams en de wonderen van go2rtc

    De nestkast-cams zijn goedkope Tuya-dingen zonder RTSP of ONVIF. De schone oplossing was geweest: andere cams kopen. Maar go2rtc heeft een Tuya-driver die met je account inlogt en de cloud-stream lokaal herpubliceert. Plotseling kan ik elk frame in een database stoppen. Een Pi praat met een NAS die praat met een Chinese cloud die praat met een nestkast in de voortuin.

§ T-07 · Eindcijfers Wat de hele setup tot nu toe opleverde

Alles uit de database, niets geschat.

Deze cijfers ververst zichzelf via een leesalleen-endpoint op de NAS. Geen tussenstap, geen edit-deploy: kijk je het over een week terug, dan zijn ze opgehoogd.

Weer
318.835
Davis VP2
23 september 2025 · 297 dagen
Vogels
1.901.302
BirdNET op 2 stations
25 november 2025 · 234 dagen
Vleermuizen
76.350
BatDetect2 + Bavaria
2 april 2026 · 106 dagen
Hemel
28.108
AtmosBird HQ camera
12 december 2025 · 217 dagen
Nestkasten
348.609
3 Tuya-cams
23 december 2025 · 206 dagen
Radar
4.207
KNMI FlySafe
12 december 2025 · 217 dagen
Audio-archief op USB ~241 GB MP3 + 447 GB spectrogrammen
Eigen getrainde modellen ~13 GB · 776 .pt-bestanden
Disaster-recovery (SD-images) ~1.9 TB
PostgreSQL-DB zelf ~2.8 GB metadata
§ T-08 · Code en bronnen Waar het werk staat

Bijna alles is open source. De website draait op Astro, de data-API is FastAPI op de NAS, de Pi-scripts staan in eigen repos. Niets staat per se ge-polijst online. Het is werkcode die loopt, maar het is te lezen.

De cijfers op deze pagina komen uit één PostgreSQL-query van onder de 50 milliseconden op de eigen NAS, gecached voor een uur. Bezoek wordt anoniem en cookieloos geteld met Umami (self-hosted) en Vercel Web Analytics. Geen advertenties, geen tracking-cookies, geen profielen. Meer daarover op de privacy-pagina.