93 lines
4.9 KiB
Python
93 lines
4.9 KiB
Python
from .i18n import tr, set_language
|
|
import argparse
|
|
import getpass
|
|
import json
|
|
import sys
|
|
|
|
|
|
def main():
|
|
language_parser = argparse.ArgumentParser(add_help=False)
|
|
language_parser.add_argument('--language', choices=['en', 'de'])
|
|
language_args, _ = language_parser.parse_known_args()
|
|
if language_args.language:
|
|
set_language(language_args.language)
|
|
parser = argparse.ArgumentParser(description=tr('Native Linux-Steuerung für den BTD 700; ohne Firmware-Updates.'))
|
|
parser.add_argument('--language', choices=['en', 'de'], help=tr('Sprache der App (Standard: Systemsprache)'))
|
|
parser.add_argument('--device', help=tr('Steuergerät aus dem Befehl devices, z. B. /dev/hidraw6'))
|
|
parser.add_argument('--background', action='store_true', help=tr('Nur im Infobereich starten'))
|
|
parser.add_argument('--demo', action='store_true', help=tr('Vorführmodus ohne USB-Zugriff'))
|
|
parser.add_argument('--smoke-seconds', type=int, default=0, help=argparse.SUPPRESS)
|
|
subs = parser.add_subparsers(dest='command')
|
|
subs.add_parser('devices', help=tr('BTD-700-Steuerschnittstellen auflisten'))
|
|
subs.add_parser('status', help=tr('Aktuellen Status als JSON ausgeben (ohne Passwort)'))
|
|
mode = subs.add_parser('mode', help=tr('Audiomodus wählen'))
|
|
mode.add_argument('value', choices=['standard', 'gaming', 'auracast'])
|
|
mode.add_argument('--transport', choices=['auto', 'classic', 'le'])
|
|
codec = subs.add_parser('codec', help=tr('Codec im Standard-Modus wählen'))
|
|
codec.add_argument('value', choices=['sbc', 'aptx', 'adaptive', 'lossless', 'qmap', 'lc3'])
|
|
subs.add_parser('connect', help=tr('Gekoppelte Kopfhörer verbinden'))
|
|
subs.add_parser('disconnect', help=tr('Kopfhörer trennen'))
|
|
broadcast = subs.add_parser('auracast', help=tr('Auracast-Einstellungen speichern'))
|
|
broadcast.add_argument('--name')
|
|
broadcast.add_argument('--password', action='store_true', help=tr('Neues Passwort verdeckt abfragen'))
|
|
broadcast.add_argument('--public', choices=['on', 'off'])
|
|
broadcast.add_argument('--encryption', choices=['on', 'off'])
|
|
broadcast.add_argument('--quality', choices=['16k', '24k', 'high'])
|
|
reset = subs.add_parser('reset', help=tr('Alle Kopplungen und Einstellungen löschen'))
|
|
reset.add_argument('--confirm', action='store_true')
|
|
args = parser.parse_args()
|
|
if not args.command:
|
|
try:
|
|
from .app import run
|
|
return run(background=args.background, demo=args.demo, device=args.device, smoke_seconds=args.smoke_seconds)
|
|
except (ImportError, ValueError) as exc:
|
|
print(tr('GTK-Oberfläche nicht verfügbar: {error}\nAbhängigkeiten: siehe README.md. CLI: ./run.sh status').format(error=exc), file=sys.stderr)
|
|
return 1
|
|
from .transport import DeviceError, Hidraw, discover
|
|
from .controller import Controller
|
|
from .protocol import ProtocolError
|
|
if args.command == 'devices':
|
|
from dataclasses import asdict
|
|
print(json.dumps([asdict(d) for d in discover()], indent=2))
|
|
return 0
|
|
transport = None
|
|
try:
|
|
if args.demo:
|
|
from .demo import DemoTransport
|
|
transport = DemoTransport()
|
|
else:
|
|
devices = [d for d in discover() if not args.device or d.path == args.device]
|
|
if len(devices) != 1:
|
|
raise DeviceError(tr('Kein eindeutiger BTD 700 gefunden. devices ausführen; bei mehreren Dongles --device angeben.'))
|
|
transport = Hidraw(devices[0])
|
|
controller = Controller(transport)
|
|
if args.command == 'mode':
|
|
controller.set_mode(['standard', 'gaming', 'auracast'].index(args.value),
|
|
{'auto': 3, 'classic': 1, 'le': 2}.get(args.transport))
|
|
elif args.command == 'codec':
|
|
controller.set_codec(1 << ['sbc', 'aptx', 'adaptive', 'lossless', 'qmap', 'lc3'].index(args.value))
|
|
elif args.command in ('connect', 'disconnect'):
|
|
controller.set_connection(args.command == 'connect')
|
|
elif args.command == 'auracast':
|
|
controller.set_broadcast(name=args.name,
|
|
password=getpass.getpass(tr('Neues Auracast-Passwort: ')) if args.password else None,
|
|
public=None if args.public is None else args.public == 'on',
|
|
encrypted=None if args.encryption is None else args.encryption == 'on',
|
|
quality={'16k': 0, '24k': 1, 'high': 2}.get(args.quality))
|
|
elif args.command == 'reset':
|
|
controller.factory_reset(confirmed=args.confirm)
|
|
print(tr('Zurücksetzen angefordert. Kopfhörer danach neu koppeln.'))
|
|
return 0
|
|
print(json.dumps(controller.snapshot().public_dict(), indent=2, ensure_ascii=False))
|
|
return 0
|
|
except (OSError, DeviceError, ProtocolError, ValueError) as exc:
|
|
print(tr('Fehler: {error}').format(error=exc), file=sys.stderr)
|
|
return 1
|
|
finally:
|
|
if transport:
|
|
transport.close()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raise SystemExit(main())
|