Skip to content

Latest commit

 

History

History
194 lines (142 loc) · 7.75 KB

File metadata and controls

194 lines (142 loc) · 7.75 KB

Xiaomi Speaker Standby Patch

Xiaomi (ve diğer) Bluetooth hoparlörlerin uzun sessizlik sonrası uyumasını engelleyen Windows uygulaması. Duyulmaz 20 kHz sinyal göndererek hoparlör DSP'sini "ses var" sanmaya ikna eder.

English version: README.en.md

Lisans Platform Python


Sorun

Bir çok Bluetooth hoparlör (özellikle Xiaomi Sound Outdoor, Mi Portable, Redmi Sound serisi) güç tasarrufu için ses sinyali yokken birkaç dakika sonra otomatik uyku moduna geçer — Bluetooth bağlantısı kopar, amfi kapanır. Tekrar müzik çalmak için manuel açma veya yeniden eşleştirme gerekir.

Sessiz WAV çalmak işe yaramaz. Hoparlör DSP'si VAD (Voice Activity Detection) kullanarak karar verir: tüm-sıfır sample'lar "ses yok" sayılır, A2DP stream açık olsa bile uyku tetiklenir.

Çözüm

Bu uygulama hoparlöre duyulmaz ama sıfır-olmayan bir sinyal gönderir:

  • Frekans: 20 kHz (yetişkin işitme sınırının üzerinde, DSP algılar)
  • Genlik: -50 dBFS (tweeter dostu, sessiz odada bile fark edilmez)
  • Profil: A2DP Stereo (HFP/Hands-Free dokunulmaz)
  • Akış: Sürekli, phase-continuous (glitch yok)

Cihaz bağlandığında sinyal otomatik başlar, koptuğunda durur. Sistem tepsisinde sessiz çalışır.

Özellikler

  • System tray uygulaması — Windows başlangıcında otomatik açılır, görünmeden çalışır
  • Tkinter pencere arayüzü — Cihaz durumu, cihaz seçimi, canlı log, kontrol butonları
  • Otomatik cihaz takibi — Bluetooth disconnect/reconnect olayları yakalanır
  • Çoklu cihaz desteği — Sadece Xiaomi değil; herhangi bir A2DP hoparlör için yapılandırılabilir
  • Sinyal testi — 3 saniyelik test sinyali çalarak hoparlörün davranışını gözlemleyin
  • PnP yeniden bağlama — Admin yetkisi varsa cihazı disable+enable ile sıfırlama
  • Rotating loglogs/patch.log (1 MB × 3 yedek)
  • Task Scheduler entegrasyonu — Logon trigger + 30 sn gecikme

Gereksinimler

  • Windows 10 veya 11
  • Python 3.10+
  • Bluetooth A2DP destekli hoparlör

Python paketleri

sounddevice>=0.5.0
numpy>=2.0.0
pystray>=0.19.0
Pillow>=10.0.0

Kurulum

# Repo'yu klonla
git clone https://github.com/baranseren/xiaomi-speaker-standby-patch.git
cd xiaomi-speaker-standby-patch

# Paketleri yükle
python -m pip install -r requirements.txt

# Tepsi ikonlarını üret (bir kez)
python assets\_generate_icons.py

# Uygulamayı manuel çalıştır (test)
python main.py

Windows başlangıcında otomatik başlatma

$taskName = "XiaomiSpeakerStandbyPatch"
$pythonw  = "$env:LOCALAPPDATA\Programs\Python\Python313\pythonw.exe"
$script   = "$PWD\main.py"

$action    = New-ScheduledTaskAction -Execute $pythonw -Argument "`"$script`"" -WorkingDirectory $PWD
$trigger   = New-ScheduledTaskTrigger -AtLogOn -User "$env:USERDOMAIN\$env:USERNAME"
$trigger.Delay = "PT30S"
$principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive -RunLevel Limited
$settings  = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Seconds 0) `
    -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -StartWhenAvailable `
    -DontStopIfGoingOnBatteries -AllowStartIfOnBatteries -MultipleInstances IgnoreNew -Hidden

Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger `
    -Principal $principal -Settings $settings -Description "Bluetooth hoparlör uyku engelleme"

Yapılandırma — config.json

{
  "device": {
    "pnp_friendly_name": "Xiaomi Sound Outdoor",
    "audio_endpoint_match": "Xiaomi Sound Outdoor Stereo"
  },
  "signal": {
    "frequency_hz": 20000,
    "amplitude_db": -50,
    "sample_rate": 48000
  },
  "polling": {
    "interval_seconds": 10
  },
  "app": {
    "autostart_signal": true,
    "minimize_to_tray_on_start": true
  },
  "logging": {
    "file": "logs/patch.log",
    "max_bytes": 1048576,
    "backup_count": 3
  }
}

Cihazınızı bulma

# Tüm bağlı Bluetooth audio endpoint'leri
Get-PnpDevice -Class AudioEndpoint | Where-Object { $_.Status -eq 'OK' } |
    Select-Object FriendlyName | Format-Table -AutoSize

audio_endpoint_match alanına hoparlörünüzün A2DP Stereo endpoint adının ayırt edici bir bölümünü yazın (Hands-Free değil).

İnce ayar

Hoparlör hâlâ uyuyorsa:

Ayar Değer Etki
amplitude_db -50 → -40 DSP daha güçlü sinyal alır, hâlâ duyulmaz
frequency_hz 20000 → 19000 Bazı genç kulaklar duyabilir, DSP kesin algılar
polling.interval_seconds 10 → 5 Disconnect/reconnect daha hızlı yakalanır

Kullanım

  • Tray ikon (sağ alt köşe ▲ menüsü):
    • Sol/çift tık → pencereyi göster
    • Sağ tık → menü (Daemon toggle / Yeniden Başlat / Cihazı Tekrar Bağla / Kapat)
  • Pencere kapatma (×) veya küçültme → tray'e gizler (uygulama kapanmaz)
  • Çıkış için: tray sağ tık → "Kapat" veya pencere alt → "Çıkış"
  • Cihaz değiştirme: Cihaz Seçimi → dropdown → "Seç ve Kaydet" → daemon otomatik yeniden başlar
  • Sinyal testi: "Sinyali Test Et (3 sn)" → 20 kHz duyulurluğunu kontrol et

Mimari

main.py        — Orkestratör: Tk root + tray thread + daemon thread
daemon.py      — KeepAliveDaemon: polling + sounddevice OutputStream + sine üreteç
gui.py         — Tkinter StatusWindow (Windows Forms 2008 klasik stili)
tray.py        — pystray Icon + menü, durum-renkli ikon değişimi
bt_devices.py  — PnP query + audio endpoint keşfi + PnP reconnect
config.json    — Cihaz, sinyal, polling, log ayarları
assets/        — Tray ikonları (active=yeşil, idle=gri, warning=amber)
logs/          — Rotating log dosyaları

Thread modeli

  • Ana thread: Tk mainloop (Windows COM/win32 thread affinity zorunlu)
  • Tray thread: pystray.Icon.run() bloklayan
  • Daemon thread: Polling + sounddevice callback
  • Tray → GUI geçişi: root.after(0, callback) ile marshal (race-safe)
  • Daemon → tray durum: her state değişiminde icon rengi güncellenir

Sıkça Sorulan Sorular

Sinyal duyuluyor mu? Yetişkin insan kulağı tipik olarak 16-17 kHz üstünü duymaz; 20 kHz @ -50 dBFS hiçbir yetişkinin işitme sınırında değildir. Genç kulaklar, köpekler ve kediler 18-20 kHz aralığında ses duyabilir — evcil hayvanınız varsa "Sinyali Test Et" ile gözlemleyin.

Tweeter'ı zorlar mı? -50 dBFS son derece düşük amplitude (yaklaşık 0.3% maksimum) — sürekli akışta bile tweeter ısıtmaz. Daha yüksek amplitude (-40 dBFS = ~1%) hâlâ güvenlidir.

Pil tüketir mi? Hoperlör pili: sinyal akarken amfi açık kalır, pil tüketimi normal kullanım gibi. Bilgisayar tarafı: sounddevice OutputStream CPU < %1.

Diğer uygulamaların sesi etkilenir mi? Hayır. WASAPI shared mode kullanılır — başka uygulamalar aynı hoperlöre ses gönderebilir, sinyaller mixlenir.

Tekrar bağlama (PnP reconnect) çalışmıyor. Admin yetkisi gerekir. Uygulamayı admin olarak çalıştır veya UAC istemini yanıtla.

Lisans

MIT © 2026 Baran SEREN

Katkı

Issue ve Pull Request açabilirsiniz. Lütfen test ettiğiniz hoparlör modelini ve config.json ayarlarınızı belirtin — başka kullanıcılar için referans olur.

Teşekkür