Système open source de monitoring de stations de radio FM basé sur Raspberry Pi / Linux et RTL-SDR, avec streaming Icecast2, décodage RDS temps réel, alertes email et interface web moderne.
- Réception FM via dongle RTL-SDR (V3, V4, compatibles RTL2832U)
- VU-mètre temps réel avec historique audio 30 secondes
- Détection de silence / perte de signal configurable
- Détection d'absence de modulation (porteuse sans programme)
- Déviation FM peak + RMS (kHz) — jauge colorée avec seuils configurables
- Niveaux L/R séparés — décodage stéréo DSB-SC depuis le signal MPX
- Ton pilote 19 kHz — détection et niveau
- Signal stéréo 38 kHz — niveau de la sous-porteuse L−R
- Sous-porteuse RDS 57 kHz — niveau RF indépendant du décodage
- Puissance MPX totale (dBFS)
- SNR — rapport signal/bruit (plancher mesuré en 60–75 kHz)
- Alerte sur-déviation — email automatique si déviation > seuil
- PS (Programme Service) — nom de la station (8 car.)
- RT (RadioText) — titre/artiste en cours (64 car.) — RT complet uniquement
- PI Code — identifiant unique hexadécimal de la station
- Logo station — récupération automatique via Radio Browser
- Serveur Icecast2 : streaming stable 24/7
- Qualité broadcast : MP3 128 kbps
- Multi-auditeurs : jusqu'à 100 connexions simultanées
- Proxy Flask HTTPS : écoute directement depuis le dashboard
- Alertes email automatiques (perte signal + rétablissement)
- Watchdog : relance automatique en cas de crash
- Historique des alertes et niveaux audio en base SQLite
- Dashboard temps réel (SSE)
- Configuration complète via interface web
- Statistiques et historique
- Page documentation (FM, MPX, RDS, dongles)
- Responsive — accessible depuis smartphone et tablette
| Dongle | Puce | Notes |
|---|---|---|
| RTL-SDR Blog V3 | RTL2832U + R820T2 | Drivers standard |
| RTL-SDR Blog V4 | RTL2832U + R828D | Recommandé — TCXO 1ppm, meilleure sensibilité. Nécessite le fork officiel |
| Nooelec NESDR SMArt | RTL2832U + R820T2 | Compatible standard |
| Autres RTL2832U | RTL2832U | Généralement compatibles |
# Bloquer le driver noyau générique
echo 'blacklist dvb_usb_rtl28xxu' | sudo tee /etc/modprobe.d/blacklist-rtl.conf
sudo modprobe -r dvb_usb_rtl28xxu 2>/dev/null
# Compiler le fork officiel
sudo apt install -y git cmake libusb-1.0-0-dev build-essential pkg-config
git clone https://github.com/rtlsdrblog/rtl-sdr-blog
cd rtl-sdr-blog && mkdir build && cd build
cmake .. -DINSTALL_UDEV_RULES=ON
make -j$(nproc) && sudo make install && sudo ldconfig
# Règles udev
sudo cp ~/rtl-sdr-blog/rtl-sdr.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger
# Test
rtl_test -t
⚠️ Bonne pratique : avant d'exécuter un script distant, inspectez-le :curl -sSL https://raw.githubusercontent.com/LyonelB/fm-monitor/main/install.sh -o install.sh less install.sh bash install.sh
Ou directement si vous faites confiance à la source :
curl -sSL https://raw.githubusercontent.com/LyonelB/fm-monitor/main/install.sh | bashLe script installe automatiquement toutes les dépendances, compile redsea, configure Icecast2, génère les certificats SSL et démarre le service.
Durée : ~10-15 minutes (compilation de redsea incluse)
- Raspberry Pi 4/5 ou mini-PC Linux (Raspberry Pi OS Lite 64-bit / Debian 13 Trixie / Ubuntu 24.04+)
- Python 3.11+
rtl_fm,redsea,ffmpeg,icecast2
git clone https://github.com/LyonelB/fm-monitor.git
cd fm-monitorpython3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtCopier et éditer le fichier de configuration :
cp config.json.example config.json
nano config.jsonParamètres clés :
{
"station": {
"name": "Ma Radio FM",
"frequency": "98.5M"
},
"rtl_sdr": {
"frequency": "98.5M",
"gain": "40"
},
"email": {
"enabled": true,
"sender_email": "votre@gmail.com",
"sender_password": "mot_de_passe_application",
"recipient_emails": ["alerte@exemple.com"]
}
}Gmail : utilisez un mot de passe d'application, pas votre mot de passe habituel.
bash generate_ssl.shsudo apt install -y icecast2Éditer /etc/icecast2/icecast.xml et définir le mot de passe source : fmmonitor2026
sudo nano /etc/systemd/system/fm-monitor.service[Unit]
Description=FM Monitor
After=network.target icecast2.service
[Service]
Type=simple
User=votre_user
WorkingDirectory=/home/votre_user/fm-monitor
ExecStart=/home/votre_user/fm-monitor/venv/bin/python3 app.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl enable fm-monitor
sudo systemctl start fm-monitorhttps://[IP-de-votre-appareil]:5000
fm-monitor/
├── app.py # Application Flask (routes, API)
├── monitor.py # Moteur de monitoring RTL-SDR / RDS
├── mpx_analyzer.py # Analyse MPX temps réel (déviation, L/R, SNR...)
├── email_alert.py # Alertes email
├── auth.py # Authentification
├── database.py # Base SQLite (historique, alertes)
├── requirements.txt # Dépendances Python
├── install.sh # Script d'installation
├── config.json.example # Exemple de configuration
├── templates/
│ ├── index.html # Dashboard principal
│ ├── config.html # Page configuration
│ ├── stats.html # Statistiques
│ ├── about.html # Documentation FM/MPX/RDS
│ └── login.html # Authentification
└── static/ # Assets CSS/JS
La page À propos intégrée dans l'interface explique :
- Le fonctionnement de la diffusion FM et du signal MPX
- Le spectre MPX : déviation, pilote 19 kHz, stéréo 38 kHz, RDS 57 kHz, puissance, SNR
- Le système RDS (PS, RT, PI Code)
- Radio Browser et la résolution de logo
- Les dongles compatibles et leur installation
lsusb | grep -i realtek
rtl_test -tSi usb_claim_interface error -6 : le driver noyau a pris le contrôle. Appliquer le blacklist (voir section V4 ci-dessus).
Vérifier la fréquence et le gain dans config.json. Tester manuellement :
rtl_fm -f 98.5M -M wbfm -s 171k -r 44100 - | aplay -r 44100 -f S16_LE- Vérifier la config SMTP dans l'interface Configuration
- Utiliser le bouton Test Email dans le dashboard
- Consulter les logs :
journalctl -u fm-monitor -f
Le RT complet prend ~20-60 secondes à se stabiliser. Vérifier que redsea est installé :
which redsea
tail -f /tmp/rds_output.json- v0.3.1 — Streaming Icecast2 professionnel, SSL, système de licences
- v0.3.2 — Open source, RTL-SDR Blog V4, logo Radio Browser, page documentation
- v0.4.0 — Script install automatique, historique niveaux audio, nettoyage interface
- v0.4.1 — Surveillance modulation + RDS, alertes multi-types, configuration étendue
- v0.4.2 — Enregistrement audio à la demande, voyant modulation, player amélioré
- v0.4.3 — Corrections durée alertes, Gunicorn, robustesse enregistrement
- v0.5.0 — Analyse MPX temps réel (déviation, L/R, pilote, stéréo, RDS RF, SNR), dashboard no-scroll
- v0.5.x — Support TEF6686 (Headless TEF Lite) — démodulation stéréo hardware, RDS natif
MIT — libre d'utilisation, modification et distribution.
- RTL-SDR Blog — drivers et matériel
- redsea — décodeur RDS
- Radio Browser — base de données stations
- Icecast2 — serveur de streaming
FM Monitor supporte deux sources matérielles, configurables dans config.json sans modifier le code.
- Brancher le TEF668X Headless en USB-C (câble données, pas charge seule)
- Vérifier la détection :
ls /dev/ttyACM0etaplay -l | grep Tuner - Ajouter la section
tefdansconfig.json:
"tef": {
"enabled": true,
"serial_port": "/dev/ttyACM0",
"alsa_device": "hw:Tuner",
"signal_threshold_dbf": 20.0,
"modulation_threshold_dbfs": -40.0
}- Installer la dépendance :
pip install pyserial --break-system-packages - Ajouter l'utilisateur au groupe dialout :
sudo usermod -a -G dialout $USER - Redémarrer :
sudo systemctl restart fm-monitor
Mettre "enabled": false dans la section tef de config.json et redémarrer.
| Fonctionnalité | RTL-SDR | TEF668X Headless |
|---|---|---|
| Signal | dBFS (RMS PCM) | dBf (RF natif) |
| Déviation FM | ✅ (MPXAnalyzer) | ❌ |
| Pilote 19 kHz | ✅ | ❌ |
| Stéréo 38 kHz | ✅ | ❌ |
| RDS 57 kHz | ✅ | ❌ |
| Stéréo/Mono | Via MPX | Via bit MS RDS |
| Niveaux L/R | ✅ | ✅ |
| SNR audio | ✅ | ✅ |
| Qualité réception | Bonne | Excellente |