- Autostart: Desktop-Entry wird in ~/.config/autostart/ erstellt - Minimiert starten: App startet direkt im System-Tray - Einstellungen lesen Config direkt, kein CLI-Flag nötig - README.md aktualisiert Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| resources | ||
| sip | ||
| ui | ||
| utils | ||
| .gitignore | ||
| build_appimage.sh | ||
| main.py | ||
| README.md | ||
| requirements.txt | ||
| sipwebapp.spec | ||
SIP Softphone
Desktop-SIP-Softphone für FreePBX/Asterisk auf Linux (KDE/PipeWire).
Basiert auf PJSUA2 (SIP-Stack) und PySide6 (Qt-GUI). Verbindet sich über SIP/UDP direkt mit der Telefonanlage.
Features
- SIP-Telefonie: Anrufe tätigen/annehmen, DTMF, Halten, Transfer, Konferenz
- Kontaktverwaltung: Lokale Kontakte + CardDAV-Sync (Nextcloud, Multi-Account)
- CardDAV Write-Back: Kontakte bearbeiten und auf den Server zurückschreiben
- Anrufliste: Verlauf mit Richtung, Dauer, Kontaktnamens-Auflösung
- Favoriten: Manuelle Favoriten + häufig angerufene Nummern (automatisch)
- BLF-Panel: Besetzt-Lampenfeld (Presence-Monitoring via SIP SUBSCRIBE)
- Kontaktsuche: Live-Suche im Wählfeld nach Name/Firma
- Responsives Layout: Kompakt (nur Wählfeld) oder Breit (Wählfeld + Tabs)
- Click-to-Call:
tel:undsip:URI-Handler via D-Bus Single-Instance - KDE-Integration: System-Tray, D-Bus-Benachrichtigungen mit Annehmen/Ablehnen
- Autostart: Automatisch beim Systemstart starten (XDG-konform)
- Minimiert starten: Optional direkt in den System-Tray starten
- PipeWire-Audio: Natives PipeWire/PulseAudio-Routing, separates Klingelton-Gerät
- AppImage: Komplett unabhängiges Paket (kein Python/Qt auf dem Zielsystem nötig)
Screenshots
┌──────────────────────────────────────────────┐
│ [Registriert] 00:42 SIP Softphone │
├──────────────┬───────────────────────────────┤
│ │ Favoriten│Verlauf│Kontakte│BLF │
│ [Nummer...] ├───────────────────────────────┤
│ │ ★ Max Mustermann │
│ [1] [2] [3]│ +49 40 555 1234 │
│ [4] [5] [6]│ ★ Büro Hauptnummer │
│ [7] [8] [9]│ +49 40 555 0000 │
│ [*] [0] [#]│ │
│ │ Häufig angerufen │
│ │ Lieferant Meyer │
├──────────────┴───────────────────────────────┤
│ [ Anrufen ] │
│ Mik: ═══════════ Lsp: ═══════════ │
└──────────────────────────────────────────────┘
Voraussetzungen
System
- Linux x86_64 (getestet: Manjaro KDE)
- PipeWire oder PulseAudio
- Python 3.10+ (für Entwicklung)
Python-Pakete
PySide6>=6.6.0
vobject>=0.9.6 # vCard-Parsing für CardDAV
requests>=2.28.0 # HTTP-Client für CardDAV
pjsua2 (SIP-Stack)
Auf Arch/Manjaro via AUR:
yay -S python-pjproject
Optional
dbus-python: Vorinstalliert auf KDE-Systemen (für Benachrichtigungen + Click-to-Call)
Installation
Aus Quellcode (Entwicklung)
git clone https://git.data-it-solution.de/data/linux.sipsoftphone.git
cd linux.sipsoftphone
pip install -r requirements.txt
python3 main.py
Als AppImage (empfohlen)
# AppImage bauen
./build_appimage.sh
# Starten
chmod +x dist/SipSoftphone-x86_64.AppImage
./dist/SipSoftphone-x86_64.AppImage
Das AppImage bündelt Python, Qt, pjsua2 und alle Abhängigkeiten. Auf dem Zielsystem wird nichts weiter benötigt.
Verwendung
Erster Start
- App starten → Login-Dialog erscheint
- SIP-Zugangsdaten eingeben (Server, Extension, Passwort, Port)
- Nach erfolgreicher Registrierung: Status wechselt zu grün "Registriert"
Anrufe
| Aktion | Bedienung |
|---|---|
| Anruf starten | Nummer eingeben + Enter oder "Anrufen"-Button |
| Kontakt anrufen | Name im Wählfeld tippen → Vorschlag doppelklicken |
| Annehmen | "Annehmen"-Button, F5, oder KDE-Benachrichtigung |
| Auflegen | "Auflegen"-Button oder F6 |
| Stummschalten | F7 |
| Halten | F8 |
| DTMF im Gespräch | Zifferntasten drücken (Wählfeld wechselt automatisch) |
CardDAV-Kontakte
Über Einstellungen → CardDAV können mehrere Accounts konfiguriert werden (z.B. Nextcloud):
- URL:
https://nextcloud.example.de/remote.php/dav - Benutzername + Passwort
- Automatischer Sync im Hintergrund
Kontakte können im Detail-Dialog bearbeitet und per CardDAV zurückgeschrieben werden.
Favoriten
- Im Kontakt-Detail-Dialog: "Favorit"-Button zum Pinnen/Entpinnen
- Häufig angerufene Nummern werden automatisch angezeigt
- Klick auf Favorit → Anruf wird gestartet
Click-to-Call (URI-Handler)
# tel: URI
python3 main.py tel:+49123456789
# sip: URI
python3 main.py sip:200@server
# Als Standard-Handler registrieren (KDE)
xdg-mime default sipwebapp.desktop x-scheme-handler/tel
xdg-mime default sipwebapp.desktop x-scheme-handler/sip
Bei laufender Instanz wird der Anruf per D-Bus an die bestehende App weitergeleitet.
Responsives Layout
- Schmal (<650px): Nur Wählfeld mit Kontaktsuche
- Breit (≥650px): Wählfeld links + Tabs rechts (Favoriten, Verlauf, Kontakte, BLF)
Projektstruktur
SipWebApp/
├── main.py # Einstiegspunkt, D-Bus Single-Instance
├── requirements.txt # Python-Abhängigkeiten
├── sipwebapp.spec # PyInstaller Build-Konfiguration
├── build_appimage.sh # AppImage Build-Skript
├── sip/
│ ├── engine.py # PJSUA2-Endpoint mit Qt-Integration
│ ├── account.py # SIP-Account (Registrierung, Presence)
│ └── call.py # SIP-Call (Medien, DTMF, Transfer)
├── ui/
│ ├── hauptfenster.py # Hauptfenster (Layout, Signale, SIP-Events)
│ ├── waehlfeld.py # Wähltastatur + Kontaktsuche
│ ├── kontakte.py # Kontakttabelle + Detail/Bearbeiten-Dialoge
│ ├── anrufliste.py # Anrufverlauf mit Namensauflösung
│ ├── favoriten_panel.py # Manuelle + automatische Favoriten
│ ├── blf_panel.py # Besetzt-Lampenfeld (SIP Presence)
│ ├── einstellungen.py # Einstellungs-Dialog (Audio, CardDAV, BLF)
│ └── login_dialog.py # SIP-Login-Dialog
├── utils/
│ ├── config_manager.py # JSON-Konfiguration (~/.config/sipwebapp/)
│ ├── carddav.py # CardDAV-Sync + Write-Back (vobject/requests)
│ ├── audio_manager.py # PipeWire/PulseAudio Geräte-Verwaltung
│ ├── klingelton.py # Klingelton über separates Audio-Gerät
│ └── benachrichtigung.py # KDE D-Bus Desktop-Benachrichtigungen
└── resources/
├── sipwebapp.desktop # XDG Desktop-Entry
├── icons/phone.svg # App-Icon
└── sounds/klingelton.wav # Standard-Klingelton
Architektur
SIP-Integration (PJSUA2)
PJSUA2 wird im Single-Thread-Modus betrieben:
threadCnt=0: Keine eigenen Worker-ThreadsmainThreadOnly=True: Alle Callbacks im Qt-HauptthreadQTimerpolltlibHandleEvents(0)alle 50ms
So werden Race-Conditions und Qt-Crash-Probleme vermieden.
Audio-Routing
PJSUA2 nutzt das pulse-Device. PipeWire übernimmt das Routing:
- Mikrofon/Lautsprecher: Konfigurierbar in den Einstellungen
- Klingelton: Separates Ausgabegerät (z.B. eingebaute Lautsprecher)
- Lautstärke: Mikrofon + Lautsprecher über Slider (0-200%)
Konfiguration
Gespeichert unter ~/.config/sipwebapp/config.json:
- SIP-Zugangsdaten (Server, Extension, Passwort)
- Audio-Geräte (Aufnahme, Wiedergabe, Klingelton)
- CardDAV-Accounts (Multi-Account)
- BLF-Extensions
- Favoriten (manuell gepinnt)
- Allgemein: Autostart, Minimiert starten, Tray-Verhalten
Autostart
Wenn in den Einstellungen aktiviert, wird ein Desktop-Entry erstellt:
~/.config/autostart/sipwebapp.desktop
Die Option "Minimiert starten" lässt die App direkt im System-Tray starten, ohne das Hauptfenster anzuzeigen.
AppImage bauen
Voraussetzungen auf dem Build-System:
- Python 3.14+
python-pjproject(AUR)- Internetzugang (lädt appimagetool + pip-Pakete)
./build_appimage.sh
Das Skript:
- Erstellt ein Python-venv mit allen Abhängigkeiten
- Kopiert pjsua2-Bindings + alle nativen Shared Libraries
- Bündelt alles mit PyInstaller
- Packt als AppImage (appimagetool)
Ergebnis: dist/SipSoftphone-x86_64.AppImage (~90 MB)
Tastatur-Shortcuts
| Taste | Aktion |
|---|---|
| F5 | Anruf annehmen |
| F6 | Auflegen |
| F7 | Stummschalten |
| F8 | Halten/Fortsetzen |
| Escape | Nummernfeld leeren |
| Enter | Nummer wählen |
| 0-9, *, # | DTMF-Ziffern (Numpad-kompatibel) |
Lizenz
Proprietär - ALLES WATT LÄUFT (Eduard Wisch)