Skip to content

baranseren/xiaomi-speaker-standby-patch

Repository files navigation

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

About

Keep your Xiaomi Bluetooth speaker awake by emitting an inaudible 20 kHz signal. System tray app for Windows with Tkinter GUI.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors