fix button mapping for OpenBikeControl, button simulator changes

This commit is contained in:
Jonas Bark
2025-12-15 09:48:36 +01:00
parent c09ab5482e
commit 968e2c5928
4 changed files with 34 additions and 20 deletions

View File

@@ -42,9 +42,11 @@ class OpenBikeControlBluetoothEmulator extends TrainerConnection {
print('Peripheral connection state: ${state.state} of ${state.central.uuid}');
if (state.state == ConnectionState.connected) {
} else if (state.state == ConnectionState.disconnected) {
core.connection.signalNotification(
AlertNotification(LogLevel.LOGLEVEL_INFO, 'Disconnected from app: ${connectedApp.value?.appId}'),
);
if (connectedApp.value != null) {
core.connection.signalNotification(
AlertNotification(LogLevel.LOGLEVEL_INFO, 'Disconnected from app: ${connectedApp.value?.appId}'),
);
}
isConnected.value = false;
connectedApp.value = null;
_central = null;
@@ -108,6 +110,7 @@ class OpenBikeControlBluetoothEmulator extends TrainerConnection {
final appInfo = OpenBikeProtocolParser.parseAppInfo(value);
isConnected.value = true;
connectedApp.value = appInfo;
supportedActions = appInfo.supportedButtons.mapNotNull((b) => b.action).toList();
core.connection.signalNotification(
AlertNotification(LogLevel.LOGLEVEL_INFO, 'Connected to app: ${appInfo.appId}'),
);
@@ -225,18 +228,20 @@ class OpenBikeControlBluetoothEmulator extends TrainerConnection {
@override
Future<ActionResult> sendAction(KeyPair keyPair, {required bool isKeyDown, required bool isKeyUp}) async {
final buttons = keyPair.buttons;
final inGameAction = keyPair.inGameAction;
final mappedButtons = connectedApp.value!.supportedButtons.filter(
(supportedButton) => buttons.any((b) => b.action == supportedButton.action),
(supportedButton) => supportedButton.action == inGameAction,
);
if (_central == null) {
if (inGameAction == null) {
return Error('Invalid in-game action for key pair: $keyPair');
} else if (_central == null) {
return Error('No central connected');
} else if (connectedApp.value == null) {
return Error('No app info received from central');
} else if (mappedButtons.isEmpty) {
return NotHandled('App does not support all buttons: ${buttons.map((b) => b.name).join(', ')}');
return NotHandled('App does not support all buttons for action: ${inGameAction.title}');
}
if (isKeyDown && isKeyUp) {
@@ -255,6 +260,6 @@ class OpenBikeControlBluetoothEmulator extends TrainerConnection {
await _peripheralManager.notifyCharacteristic(_central!, _buttonCharacteristic, value: responseData);
}
return Success('Buttons ${buttons.map((b) => b.name).join(', ')} sent');
return Success('Buttons ${inGameAction?.title} sent');
}
}

View File

@@ -137,6 +137,8 @@ class OpenBikeControlMdnsEmulator extends TrainerConnection {
final appInfo = OpenBikeProtocolParser.parseAppInfo(Uint8List.fromList(data));
isConnected.value = true;
connectedApp.value = appInfo;
supportedActions = appInfo.supportedButtons.mapNotNull((b) => b.action).toList();
core.connection.signalNotification(
AlertNotification(LogLevel.LOGLEVEL_INFO, 'Connected to app: ${appInfo.appId}'),
);
@@ -160,19 +162,21 @@ class OpenBikeControlMdnsEmulator extends TrainerConnection {
@override
Future<ActionResult> sendAction(KeyPair keyPair, {required bool isKeyDown, required bool isKeyUp}) async {
final buttons = keyPair.buttons;
final inGameAction = keyPair.inGameAction;
final mappedButtons = connectedApp.value!.supportedButtons.filter(
(supportedButton) => buttons.any((b) => b.action == supportedButton.action),
(supportedButton) => supportedButton.action == inGameAction,
);
if (_socket == null) {
if (inGameAction == null) {
return Error('Invalid in-game action for key pair: $keyPair');
} else if (_socket == null) {
print('No client connected, cannot send button press');
return Error('No client connected');
} else if (connectedApp.value == null) {
return Error('No app info received from central');
} else if (mappedButtons.isEmpty) {
return NotHandled('App does not support all buttons: ${buttons.map((b) => b.name).join(', ')}');
return NotHandled('App does not support: ${inGameAction.title}');
}
if (isKeyDown && isKeyUp) {
@@ -191,7 +195,7 @@ class OpenBikeControlMdnsEmulator extends TrainerConnection {
_write(_socket!, responseData);
}
return Success('Sent ${buttons.map((b) => b.name).join(', ')} button press');
return Success('Sent ${inGameAction.title} button press');
}
void _write(Socket socket, List<int> responseData) {

View File

@@ -1,11 +1,11 @@
import 'package:flutter/foundation.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:flutter/foundation.dart';
abstract class TrainerConnection {
final String title;
final List<InGameAction> supportedActions;
List<InGameAction> supportedActions;
final ValueNotifier<bool> isStarted = ValueNotifier(false);
final ValueNotifier<bool> isConnected = ValueNotifier(false);

View File

@@ -1,17 +1,19 @@
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart' show BackButton;
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:bike_control/bluetooth/devices/trainer_connection.dart';
import 'package:bike_control/pages/touch_area.dart';
import 'package:bike_control/utils/actions/android.dart';
import 'package:bike_control/utils/actions/base_actions.dart';
import 'package:bike_control/utils/actions/desktop.dart';
import 'package:bike_control/utils/core.dart';
import 'package:bike_control/utils/i18n_extension.dart';
import 'package:bike_control/utils/keymap/buttons.dart';
import 'package:bike_control/utils/keymap/keymap.dart';
import 'package:bike_control/widgets/ui/gradient_text.dart';
import 'package:bike_control/widgets/ui/toast.dart';
import 'package:bike_control/widgets/ui/warning.dart';
import 'package:dartx/dartx.dart';
import 'package:flutter/material.dart' show BackButton;
import 'package:flutter/services.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart';
class ButtonSimulator extends StatefulWidget {
const ButtonSimulator({super.key});
@@ -328,7 +330,7 @@ class _ButtonSimulatorState extends State<ButtonSimulator> {
);
return;
} else {
await connection.sendAction(
final result = await connection.sendAction(
KeyPair(
buttons: [],
physicalKey: null,
@@ -338,6 +340,9 @@ class _ButtonSimulatorState extends State<ButtonSimulator> {
isKeyDown: down,
isKeyUp: !down,
);
if (result is! Success) {
buildToast(context, title: result.message);
}
}
}