Skip to main content

heybike

Python control and firmware-update helpers for Heybike e-bikes.

heybike wraps the Heybike account APIs and the bike's BLE protocol in a small async Python interface. It can find bikes from your account, scan for nearby Heybike BLE advertisements, read common bike state, change controller/display settings, and apply supported firmware updates.

This is an unofficial package. I have only been able to test it against the bikes I own, primarily a Heybike Cityrun 1.0, so expect some model-specific edges.


Installation

python -m pip install heybike

Bluetooth access is provided by bleak, so your machine needs a working Bluetooth adapter and the usual OS-level BLE permissions.


Quickstart

import asyncio

from heybike import Heybike

EMAIL = "you@example.com"
PASSWORD = "your-heybike-password"


async def main():
    bike = next(Heybike.account_bikes(email=EMAIL, password=PASSWORD))

    info = await bike.get_base_info()
    print(bike.name, bike.mac)
    print(f"battery: {info.battery_percent}%")
    print(f"power: {info.power_on}")

    await bike.set_headlight(True)
    await bike.set_power(False)


asyncio.run(main())

Most bike operations are async because they connect to the bike over BLE.


Finding bikes

Get the bikes already associated with your Heybike account:

from heybike import Heybike

for bike in Heybike.account_bikes(email=EMAIL, password=PASSWORD):
    print(bike.name, bike.mac, bike.model.name if bike.model else "")

Scan for nearby Heybike BLE advertisements:

import asyncio

from heybike import Heybike


async def main():
    async for bike in Heybike.nearby_bikes(
        scan_seconds=10,
        email=EMAIL,
        password=PASSWORD,
    ):
        print(bike.name, bike.mac)


asyncio.run(main())

The optional HEYBIKE_BLE_KEY_CACHE environment variable can point at a CSV file used to cache BLE keys:

set HEYBIKE_BLE_KEY_CACHE=%USERPROFILE%\.heybike_ble_keys.csv

Bike state and controls

Common read methods:

  • get_base_info() for battery, power, auto-lock, hardware, firmware, and protocol versions.
  • get_battery_percent(), get_power(), get_mileage(), get_imei(), and get_icc_id().
  • get_signal_gps() for cellular/GPS signal levels.
  • get_auto_lock_info() and get_anti_theft().

Common write methods:

  • set_power(...), toggle_power(), and set_headlight(...).
  • set_auto_lock(...) and set_anti_theft(...).
  • set_max_speed(...), set_speed_unit(...), set_drive_gear(...), and set_start_gear(...).
  • set_backlight_brightness(...), set_ride_feel(...), set_preset_mode(...), and set_throttle_sensitivity(...).
  • reset_trip_distance(), reset_to_default(), and sync_controller_time().

Example:

async def configure(bike: Heybike):
    await bike.sync_controller_time()
    await bike.set_speed_unit(1)  # 0 = km, 1 = mile
    await bike.set_auto_lock(True, time=10)
    await bike.set_backlight_brightness(3)

Firmware updates

heybike can ask the Heybike API whether an OTA update is available, download it, and transfer it over BLE using the YMODEM variant used by supported bikes.

import asyncio

from heybike import Heybike


async def main():
    bike = next(Heybike.account_bikes(email=EMAIL, password=PASSWORD))

    update = await bike.check_for_updates()
    if update is None:
        print("Already current")
        return

    print(f"{update.current_version} -> {update.version}")
    await bike.update(
        update_info=update,
        progress_callback=lambda progress: print(f"{progress}%"),
    )


asyncio.run(main())

You can also pass a local firmware image to update(...), but firmware updates are inherently risky. Make sure the image and OTA mode match your bike.


Catalog metadata

The package exposes a small amount of model/color metadata from the Heybike APIs:

from heybike import Heybike

models = Heybike.bike_models(email=EMAIL, password=PASSWORD)
for model in models:
    print(model.name, [color.name for color in model.colors])

The main public data classes are BaseInfo, AutoLockInfo, AntiTheftInfo, SignalGpsInfo, BikeModelInfo, BikeColorInfo, BikeIdentityInfo, and FirmwareUpdate.


Notes

  • Use this only with bikes you own or are authorized to work on.
  • Heybike can change their app, APIs, firmware formats, or BLE behavior at any time.
  • Firmware transfer support is currently centered on the YMODEM update flow.
  • The research notes and protocol background live in research/, but normal package use should not require reading them.

Release files for heybike 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for heybike 0.0.1
File Size Uploaded
heybike-0.0.1.tar.gz 22.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for heybike 0.0.1
File Interpreter ABI Platform
heybike-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 43.8 kB

Release files / heybike-0.0.1.tar.gz

Download URL heybike-0.0.1.tar.gz
Size 22.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e40090fba1ec1f68e58185d279744605e0b6d211ac0c573668e988e566dcf9fa
BLAKE2b-256 checksum
How to use checksums
014b56aa2b8e4b9c465f87eab103eb14ed7425deb3cf65f10ee0d6476f2d0446
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / heybike-0.0.1-py3-none-any.whl

Download URL heybike-0.0.1-py3-none-any.whl
Size 21.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
643dfa54d250e70ce973fe6d6913a286a9bf3fd1e6642ebe36b35ed06f4bb10d
BLAKE2b-256 checksum
How to use checksums
e25a50360ac372e1aa4cb954bace50f2a7da061de5f99a0d425936c747c6b10f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page