EMSN
Nijverdal · Veldjournaal

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 02:26:26

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
    12%
    RAM
    34%
    Disk
    70%
    Temp 51.0 °C Uptime 27.4d
  • Struikgewas

    AtmosBird hemelcamera

    CPU
    15%
    RAM
    32%
    Disk
    66%
    Temp 52.7 °C Uptime 1.5d
  • Sonar

    BatDetect2 ultrasoon

    CPU
    61%
    RAM
    15%
    Disk
    19%
    Temp 50.1 °C Uptime 27.4d
  • Meteo

    Davis VP2

    CPU
    9%
    RAM
    48%
    Disk
    23%
    Temp 58.0 °C Uptime 2.7d
  • NAS

    Postgres, opslag, mail, web

    CPU
    RAM
    Disk
    Temp Uptime 29.1d
  • 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

259.124 records · 252 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.359.993 records · 189 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

17.216 records · 61 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

263.568 records · 161 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

21.655 records · 172 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

2.043 records · 172 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
259.124
Davis VP2
23 september 2025 · 252 dagen
Vogels
1.359.993
BirdNET op 2 stations
25 november 2025 · 189 dagen
Vleermuizen
17.216
BatDetect2 + Bavaria
2 april 2026 · 61 dagen
Hemel
21.655
AtmosBird HQ camera
12 december 2025 · 172 dagen
Nestkasten
263.568
3 Tuya-cams
23 december 2025 · 161 dagen
Radar
2.043
KNMI FlySafe
12 december 2025 · 172 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.