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

PlatformKeyboardMouse / touchMedia keysPermission
Windowsusually none
macOSAccessibility / keyboard access
Android✅ (taps & long tap)Accessibility Service
iOS / iPadOSnot 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 trainer app card on BikeControl's main page: MyWhoosh, "Waiting for MyWhoosh", an Edit button, and a checklist whose last, optional step is "Add keyboard and mouse actions"

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.

BikeControl's Setup Trainer section — the trainer app picker set to MyWhoosh, and the target row with "This Device" selected

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:

The Local connection tile, titled "Control MyWhoosh using Keyboard, Touch, Media", with its toggle switched on and an Instructions button

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

The permission sheet reading "The following permissions are required:" with a single "Keyboard access" row and a Grant button

  • 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:

BikeControl's mapping table for a Zwift Click — Shift Up Right mapped to "K (Shift Up)" and Shift Up Left to "I (Shift Down)", each with empty Double Click and Long Press rows

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 17 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.

The button editor for shiftUpRight, Editing Single Click, with "Press a keyboard key — Arrow Up" selected, plus "Click any button on screen" and "Control Music playback" options

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:

A dialog reading "Press a key on your keyboard to assign to Shift Up Right" with "Waiting..." underneath and an OK button

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.

The button editor for shiftUpLeft with "Click any button on screen — X:80, Y:94 (Shift Down)" selected

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.

BikeControl's placement editor over a MyWhoosh in-game screenshot, with a draggable target labelled "X:80, Y:94 (Shift Down)" sitting on MyWhoosh's on-screen gear arrows, and Save / Menu buttons top right

The flow the app walks you through:

  1. Take an in-game screenshot of your trainer app, in landscape
  2. Load that screenshot with the button on screen
  3. BikeControl switches itself to landscape so the mapping lines up
  4. Press a button on your controller to create a click target for it
  5. Drag the target onto the app's on-screen button
  6. 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 mapping table after editing — Shift Up Right on "Arrow Up (Shift Up)" and Shift Up Left on "X:80, Y:94 (Shift Down)"

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:

The button editor on Android: "Click any button on screen — X:80, Y:94 (Shift Down)", "Control Music playback", "Android System Action", "Open Assistant" (Pro), and "Broadcast Custom Intent — For automation apps like MacroDroid or Tasker" (Pro)

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.