Go library for controlling QCY Bluetooth earphones on Linux via BLE GATT.
Proof of concept. No guarantee it will work properly. Use at your own risk.
go get github.com/hui1601/Quicky
Requires BlueZ on Linux.
package main import ( "fmt" quicky "github.com/hui1601/Quicky/lib" ) func main() { scanner := quicky.NewScanner() scanner.Scan(func(result quicky.ScanResult) { fmt.Printf("Found: %s (RSSI: %d)\n", result.Address.String(), result.RSSI) if result.Advertisement != nil { fmt.Printf(" Battery: L=%d%% R=%d%% Box=%d%%\n", result.Advertisement.LeftBattery, result.Advertisement.RightBattery, result.Advertisement.BoxBattery) fmt.Printf(" Control MAC: %s\n", result.Advertisement.ControlMAC) if product, ok := result.GetProductInfo(); ok { fmt.Printf(" Model: %s\n", product.Title) if product.Features.ANC != nil { fmt.Printf(" ANC: %d modes\n", len(product.Features.ANC.Modes)) } } } }) }
package main import ( "context" "fmt" "time" quicky "github.com/hui1601/Quicky/lib" ) func main() { client, _ := quicky.New("AA:BB:CC:DD:EE:FF") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client.Connect(ctx) defer client.Disconnect() battery, _ := client.ReadBattery() fmt.Printf("Battery: L=%d%% R=%d%% Box=%d%%\n", battery.Left.Level, battery.Right.Level, battery.Box.Level) client.SetNoiseCancelMode(quicky.NoiseCancelANC) client.SetLowLatency(true) client.SetVolume(80, 80) }
go func() { for ev := range client.Events() { fmt.Printf("Event: type=%d cmdID=0x%02x\n", ev.Type, ev.CmdID) } }()
- Discovery — Scan for QCY devices via BLE manufacturer data (CompanyID
0x521c), parse battery levels, charging state, and MAC addresses from advertisements - Model identification — Embedded product database (199 models) maps vendorId to model name and supported features (ANC, EQ, etc.)
- 40+ commands — Noise cancellation, EQ (v1/v2/per-channel), key function mapping, LED effects, spatial audio, wearing detection, alarms, music control, and more
- Event stream — Async notification handling with typed event parsing
- Direct reads — Battery and firmware version via characteristic reads