Get the Most Out of BikeControl with the Local Connection Method
By Jonas Bark · August 18, 2026
Most of BikeControl's connection methods are about talking to another device: your phone holds the controller connection, your PC or Apple TV runs the trainer app, and the two meet over Bluetooth or your network.
The Local connection method is the opposite, and it's the one people overlook. Everything happens on one machine: BikeControl and your trainer app run side by side, and BikeControl controls the app the same way you would — by pressing keys, clicking the screen, and hitting media keys.
No network. No second device. No protocol the trainer app has to support. If the app has a keyboard shortcut or an on-screen button, your handlebar controller can reach it.
This is the first post in our new Tutorials series: one feature, start to finish, with the real screens you'll see.
What Local actually does
Local is input simulation. When you press a button on your Zwift Click, CYCPLUS BC2 or Zwift Play, BikeControl:
- presses a keyboard key — with modifiers if you want, e.g.
Ctrl+Alt+R - clicks (or taps) a position on screen — the spot where the app draws its own button
- sends a media key — play/pause, next, previous, volume
That's it. Because it's the same input a human produces, it works with apps that have no controller integration at all — and with the parts of apps that do have an integration but never exposed a particular action.
The trade-off is honest and worth stating up front: Local can only reach the device it's running on, and keyboard shortcuts only do something if the trainer app actually listens for that key. It's the simplest method to set up and the least clever one.
What it needs
| Platform | Keyboard | Mouse / touch | Media keys | Permission |
|---|---|---|---|---|
| Windows | ✅ | ✅ | ✅ | usually none |
| macOS | ✅ | ✅ | ✅ | Accessibility / keyboard access |
| Android | — | ✅ (taps & long tap) | ✅ | Accessibility Service |
| iOS / iPadOS | — | — | — | not available |
Two things to take away from that table:
Android has no keyboard row. Emulating keyboard input isn't possible on Android — the platform gives no app a way to type into another one. What it does allow, through the Accessibility Service, is dispatching touches, so on a phone or tablet Local works by tapping the screen.
iOS is not on the list at all. Apple doesn't let one app synthesize input into another, so on iPhone and iPad BikeControl has to reach the trainer app a different way — the OpenBikeControl connection, MyWhoosh Link, or Zwift's own protocol. That's not a BikeControl limitation we can lift.
Step 1 — Open Trainer Connections
Everything below lives in one screen, and the way in is the trainer app card on BikeControl's main page — the third link in the setup chain, under your controller and your trainer. Tap Edit on it.

The card is also where BikeControl tells you Local exists: the last item on its checklist, marked optional, is "Add keyboard and mouse actions". It stays there, unticked, for as long as you don't use it — because nothing breaks without it, and nothing tells you about it either.
Step 2 — Tell BikeControl the app runs on this device
Local only appears once BikeControl knows the trainer app is on the same machine. In Trainer Connections, pick your trainer app, then pick This Device as the target.

Pick Other Device here and the Local tile disappears, replaced by the network and Bluetooth methods. That's the single most common reason people can't find Local: the target is still set to another device.
Step 3 — Switch Local on
With the target set, the Local tile shows up in the list of connection methods. Its title tells you exactly what your platform can do — here, on macOS, all three modes:

Flip the toggle. If a permission is missing, BikeControl asks for exactly the one it needs instead of a wall of requests:

- On macOS, Grant opens System Settings at the right pane. If BikeControl isn't in the list yet, add it manually — the app tells you the same thing in a toast.
- On Android, you first get a plain-language disclosure of what the Accessibility Service is used for, then the system settings screen.
- On Windows, you usually won't see this sheet at all.
The green dot on the tile means Local is live. The Instructions button opens the same explanation inside the app, offline.
Step 4 — Start from the predefined keymap
You don't start from a blank sheet. BikeControl ships a keymap for each supported app, so a freshly enabled Local setup already shifts:

For MyWhoosh that's K to shift up and I to shift down, plus A/D for steering, the arrow keys for navigation, H to toggle the UI, and 1–7 for emotes. Other apps ship their own set. Which keys are available is up to the trainer app, not up to BikeControl — we can only press what the app is listening for.
Notice the three rows per button: Single Click, Double Click and Long Press. Every one of them is a separate assignment, which is what turns a two-button shifter into up to six actions (double click needs BikeControl Pro).
Step 5 — Assign your own keyboard hotkey
Tap a row to open that button's editor — or just press the button on your controller, and BikeControl opens the editor for the button you pressed. Press a different one and the editor follows along.
The first time you edit a shipped keymap, BikeControl quietly copies it into a profile of your own — MyWhoosh (Copy) — and tells you so. The defaults you started from stay untouched, so you can always switch back in the keymap picker, and with Pro your profiles sync across your devices.

Under Local / Remote Setting, choose Press a keyboard key. You get a menu with your app's predefined actions and a Custom entry. Custom opens the listener:

Now press the key you want. Hold modifiers and they're captured too: Shift, Ctrl, Alt, Meta and Fn combine into a single shortcut like Ctrl+Alt+R, which is how you reach an app's less common commands without giving up a plain letter key. Confirm with OK.
One detail worth knowing about how the key is delivered: for MyWhoosh and Rouvy, BikeControl targets that application's process directly. For every other app, key events go out globally — to whichever window currently has focus. So if you're mapping keys for some other app, keep it in the foreground, and don't be surprised if a stray shift lands in your chat window.
Step 6 — Emulate a mouse click
Some things a trainer app only offers as an on-screen button. That's what Click any button on screen is for.

Pick it and BikeControl opens a full-screen placement editor: your own in-game screenshot as the backdrop, and a draggable target for every button you've mapped a click to.

The flow the app walks you through:
- Take an in-game screenshot of your trainer app, in landscape
- Load that screenshot with the button on screen
- BikeControl switches itself to landscape so the mapping lines up
- Press a button on your controller to create a click target for it
- Drag the target onto the app's on-screen button
- Save and close
Above, the target sits on MyWhoosh's on-screen gear arrows — bottom right, next to the gear readout. That is not a coincidence: for apps BikeControl knows, the shipped keymap already carries click positions, so X:80, Y:94 was filled in for you and you're adjusting rather than starting from scratch.
The positions are stored as percentages of the screen — that's why the editor shows X:80, Y:94 and not a pixel pair. Change your window size or your resolution and the target still lands in the same relative place. On desktop these become real mouse clicks; on Android, real taps — and because the touch down and touch up are dispatched separately, holding your controller button holds a finger on the screen, which is how a long tap gets through.
The result
Both mappings, side by side, in the same table you started from:

The label always tells you what a button will do: a key name for keyboard actions, X:…, Y:… for a click, an action name where the app knows one.
What the same editor looks like on Android
Everything above was macOS. On a phone or tablet the button editor offers a different set — and this is the clearest way to see what the platform allows:

No "Press a keyboard key" — emulating keyboard input isn't possible on Android. What you get instead:
- Click any button on screen — the same percentage-based target, dispatched as a real tap
- Control Music playback — play/pause, stop, next, previous, volume (Pro)
- Android System Action — Back, Home, Recents, Select and the four D-pad directions, so a controller button can drive the system, not just the app: navigating a menu, or getting out of one, without touching the screen
- Open Assistant (Pro)
- Broadcast Custom Intent (Pro) — fires an intent for automation apps like MacroDroid or Tasker, i.e. a handlebar button that triggers anything you can automate on the phone: lights, a fan, a scene
Beyond the trainer app
The same idea on desktop, under Other Actions:
- Control music playback, so you don't have to reach for the laptop mid-interval (Pro)
- Launch a shortcut (macOS) or run a command (Windows) (Pro)
- Take a screenshot (Pro)
- Record the screen (Pro)
That's the part riders tend to discover by accident and then keep: skipping a track from the handlebars.
Where Local falls short
Being straight about it, because picking the wrong method wastes an evening:
- One device only. Trainer app on the PC and BikeControl on your phone? That's not Local — use the network or Bluetooth methods.
- The app has to listen. No keyboard shortcut for an action means no keyboard mapping for it. A click target is often the workaround.
- Focus matters for every app except MyWhoosh and Rouvy, where BikeControl targets the process directly.
- Timing-sensitive interfaces can be finicky — a simulated click is not always as reliable as a native integration.
- If your app has an official integration, prefer it. For apps that speak OpenBikeControl — MyWhoosh, TrainingPeaks Virtual, Strappo and others — the native path gives real button events instead of synthesized input. Local is what you use when that path doesn't exist, or when you want actions the integration doesn't cover.
Troubleshooting
Android: nothing happens after enabling. The Accessibility Service was probably killed by the system. BikeControl detects this and links to dontkillmyapp.com — on Xiaomi, Redmi and POCO devices you'll also want to disable battery optimization for BikeControl, enable autostart, and lock the app in recents. The app shows this warning itself when it recognizes a MIUI device.
Android: clicks land in the wrong spot. Auto-rotation has to be enabled — BikeControl warns you when it isn't. Placement assumes landscape.
macOS: keys do nothing. Check Accessibility again: BikeControl has to be in the list and ticked. Re-granting after an app update is occasionally necessary.
The right key, the wrong result. Make sure the trainer app itself is focused, and that the shortcut still exists — apps do change their key bindings between versions.
Frequently Asked Questions
Is the Local connection method free? Yes. Local, the keyboard and click mappings, and the predefined keymaps are part of BikeControl. Double-click assignments, media keys and launching shortcuts are Pro features.
Why can't I see the Local option? Either the target is set to "Other Device" instead of "This Device", or you're on iOS/iPadOS, where input simulation isn't possible. Local is available on Windows, macOS and Android.
Does Local work with any trainer app? It works with any app you can drive by keyboard or by clicking — including apps BikeControl has no integration with. What varies is how much the app exposes: some have a rich set of shortcuts, some almost none.
Can I use Local together with another connection method? Yes. Local can run alongside the other methods, and the button editor groups the available actions by the path they take — so you can see at a glance which one a button uses. A common setup is a native integration for shifting plus Local for media keys.
Do I need to remap everything after changing my screen resolution? No. Click targets are stored as percentages of the screen, so they scale with it. You only need to remap when the trainer app itself moves its buttons.