-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Add Specialized Turbo integration docs #44119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JamieMagee
wants to merge
5
commits into
home-assistant:next
Choose a base branch
from
JamieMagee:add-specialized-turbo-docs
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
09156f8
Add Specialized Turbo integration docs
JamieMagee 3f01192
Fix docs review: raw tags, indentation, breadcrumb
JamieMagee bca5c20
Remove invalid Bluetooth glossary term reference
JamieMagee 38b9f4b
PR review comments
JamieMagee 6687387
Address review comments
JamieMagee File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,249 @@ | ||
| --- | ||
| title: Specialized Turbo | ||
| description: Read telemetry from Specialized Turbo e-bikes over Bluetooth Low Energy in Home Assistant. | ||
| ha_category: | ||
| - Sensor | ||
| ha_release: "2026.4" | ||
| ha_iot_class: Local Push | ||
| ha_config_flow: true | ||
| ha_codeowners: | ||
| - '@JamieMagee' | ||
| ha_domain: specialized_turbo | ||
| ha_integration_type: device | ||
| ha_quality_scale: bronze | ||
| ha_platforms: | ||
| - sensor | ||
| ha_bluetooth: true | ||
| related: | ||
| - docs: /docs/configuration/troubleshooting/#debug-logs-and-diagnostics | ||
| title: Debug logs and diagnostics | ||
| - docs: /integrations/bluetooth/ | ||
| title: Bluetooth | ||
| --- | ||
|
|
||
| The **Specialized Turbo** {% term integration %} connects Home Assistant to [Specialized](https://www.specialized.com/) Turbo e-bikes over Bluetooth Low Energy. It reads real-time telemetry straight from the bike — battery level, speed, power output, cadence, motor temperature, odometer, and more — giving you the same data the Specialized Mission Control app sees. | ||
|
|
||
| If you ride a Specialized Turbo Vado, Levo, Creo, Como, or Tero, you can track battery health over time, log rides through Home Assistant's history, or build automations that fire when your bike finishes charging. | ||
|
|
||
| ## Supported devices | ||
|
|
||
| This integration works with Specialized Turbo e-bikes that have the Gen 2 BLE module (the TURBOHMI2017 protocol), which includes most 2017 and newer models with a <abbr title="Turbo Connect Unit">TCU</abbr> display: | ||
|
|
||
| - Turbo Vado (all SL and full-power variants) | ||
| - Turbo Levo (all SL and full-power variants) | ||
| - Turbo Creo (all SL and full-power variants) | ||
| - Turbo Como (SL and full-power) | ||
| - Turbo Tero | ||
|
|
||
| If your bike broadcasts a TURBOHMI Bluetooth advertisement when powered on, it should work. | ||
|
|
||
| ## Unsupported devices | ||
|
|
||
| - Older Specialized bikes without a TCU display | ||
| - Non-Turbo Specialized bikes (road, mountain, gravel without a motor) | ||
| - Third-party e-bikes | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Before setting up this integration, make sure: | ||
|
|
||
| 1. Your bike is powered on and awake (pedal or press the power button — the TCU screen should be lit). | ||
| 2. Home Assistant has access to a [Bluetooth adapter](/integrations/bluetooth/). If the bike is out of range, you can use an [ESPHome Bluetooth proxy](https://esphome.io/projects/?type=bluetooth) placed in your garage or shed. | ||
| 3. No other app (like Specialized Mission Control) is actively connected to the bike over Bluetooth. Only one BLE client can connect at a time. | ||
|
|
||
| {% include integrations/config_flow.md %} | ||
|
|
||
| The bike is usually discovered automatically. If it doesn't appear, make sure it's powered on and within Bluetooth range, then try adding it manually through {% my integrations title="**Settings** > **Devices & services**" %}. | ||
|
|
||
| {% configuration_basic %} | ||
| Pairing PIN: | ||
| description: "The PIN displayed on the bike's TCU screen during Bluetooth pairing. Leave empty if your bike does not require a PIN." | ||
| {% endconfiguration_basic %} | ||
|
|
||
| ## Supported functionality | ||
|
|
||
| ### Entities | ||
|
|
||
| The **Specialized Turbo** integration provides the following sensor entities. | ||
|
|
||
| #### Sensors | ||
|
|
||
| - **Battery** | ||
| - **Description**: Current battery charge level, as a percentage. | ||
|
|
||
| - **Battery capacity** | ||
| - **Description**: Total battery capacity in watt-hours. | ||
|
|
||
| - **Battery remaining** | ||
| - **Description**: Remaining battery energy in watt-hours. | ||
|
|
||
| - **Battery health** | ||
| - **Description**: Battery health percentage. Useful for tracking degradation over time. | ||
| - **Category**: Diagnostic | ||
|
|
||
| - **Battery temperature** | ||
| - **Description**: Battery temperature in °C. | ||
| - **Category**: Diagnostic | ||
|
|
||
| - **Charge cycles** | ||
| - **Description**: Total number of charge cycles the battery has completed. | ||
| - **Category**: Diagnostic | ||
|
|
||
| - **Battery voltage** | ||
| - **Description**: Current battery voltage. | ||
| - **Category**: Diagnostic | ||
|
|
||
| - **Battery current** | ||
| - **Description**: Current draw from the battery in amps. | ||
| - **Category**: Diagnostic | ||
|
|
||
| - **Speed** | ||
| - **Description**: Current speed in km/h. | ||
|
|
||
| - **Rider power** | ||
| - **Description**: Power you're putting through the pedals, in watts. | ||
|
|
||
| - **Motor power** | ||
| - **Description**: Power the electric motor is adding, in watts. | ||
|
|
||
| - **Cadence** | ||
| - **Description**: Pedaling cadence in RPM. | ||
|
|
||
| - **Odometer** | ||
| - **Description**: Total distance the bike has traveled, in kilometers. | ||
|
|
||
| - **Motor temperature** | ||
| - **Description**: Motor temperature in °C. | ||
| - **Category**: Diagnostic | ||
|
|
||
| - **Assist level** | ||
| - **Description**: Current assist mode — Off, Eco, Trail, or Turbo. | ||
|
|
||
| - **ECO assist** | ||
| - **Description**: Assist percentage configured for ECO mode. | ||
| - **Category**: Diagnostic | ||
| - **Remarks**: Disabled by default. | ||
|
|
||
| - **Trail assist** | ||
| - **Description**: Assist percentage configured for Trail mode. | ||
| - **Category**: Diagnostic | ||
| - **Remarks**: Disabled by default. | ||
|
|
||
| - **Turbo assist** | ||
| - **Description**: Assist percentage configured for Turbo mode. | ||
| - **Category**: Diagnostic | ||
| - **Remarks**: Disabled by default. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Notify when the battery is fully charged | ||
|
|
||
| ```yaml | ||
| - alias: "Bike battery full" | ||
| triggers: | ||
| - trigger: numeric_state | ||
| entity_id: sensor.specialized_turbo_battery | ||
| above: 99 | ||
| actions: | ||
| - action: notify.mobile_app | ||
| data: | ||
| message: "Your bike is fully charged!" | ||
| ``` | ||
|
|
||
| ### Warn when battery health drops | ||
|
|
||
| {% raw %} | ||
|
|
||
| ```yaml | ||
| - alias: "Bike battery health warning" | ||
| triggers: | ||
| - trigger: numeric_state | ||
| entity_id: sensor.specialized_turbo_battery_health | ||
| below: 80 | ||
| actions: | ||
| - action: notify.mobile_app | ||
| data: | ||
| message: > | ||
| Bike battery health is at | ||
| {{ states( | ||
| 'sensor.specialized_turbo_battery_health' | ||
| ) }}%. | ||
| Consider scheduling a service. | ||
| ``` | ||
JamieMagee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| {% endraw %} | ||
|
|
||
| ## Data updates | ||
|
|
||
| The integration uses a push-based approach. It connects to the bike over Bluetooth, subscribes to GATT notifications on the telemetry characteristic, and receives updates whenever the bike broadcasts new data. No polling is performed. If the Bluetooth connection drops, the integration reconnects automatically the next time it sees the bike's advertisement. | ||
|
|
||
| ## Known limitations | ||
|
|
||
| - **Bluetooth range**: The bike needs to be within about 5–10 meters of a Bluetooth adapter. For a garage or shed, an [ESPHome Bluetooth proxy](https://esphome.io/projects/?type=bluetooth) works well. | ||
| - **One connection at a time**: Only one BLE client can connect to the bike simultaneously. If the Specialized Mission Control app is connected, Home Assistant can't connect, and vice versa. | ||
| - **Read-only**: The integration reads telemetry only. It cannot change assist levels, adjust settings, or send commands to the bike. | ||
| - **Sleep mode**: When the bike enters sleep mode, Bluetooth advertisements stop and the connection drops. Data resumes when you wake the bike up. | ||
| - **Secondary battery**: Range-extender battery data is parsed internally but not exposed as sensor entities. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Bike not discovered | ||
|
|
||
| #### Symptom: The bike doesn't appear during setup | ||
|
|
||
| When you try to add the integration, your bike is not listed as a discovered device. | ||
|
|
||
| #### Description | ||
|
|
||
| The bike may be asleep, out of Bluetooth range, or the Bluetooth adapter in Home Assistant may not be picking up its advertisement. | ||
|
|
||
| #### Resolution | ||
|
|
||
| To resolve this issue, try the following steps: | ||
|
|
||
| 1. Make sure the bike is powered on and awake. Pedal briefly or press the power button so the TCU screen lights up. | ||
| 2. Check that your Bluetooth adapter is working in {% my integrations title="**Settings** > **Devices & services**" %}. | ||
| 3. If you're using an ESPHome Bluetooth proxy, confirm that `active: true` is set in the proxy's configuration. | ||
| 4. Move the bike closer to the Bluetooth adapter. BLE range is typically 5–10 meters, less through walls. | ||
|
|
||
| ### Sensors show "Unavailable" | ||
JamieMagee marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #### Symptom: All sensors show "Unavailable" | ||
|
|
||
| After the integration is set up, one or more sensor entities show **Unavailable** instead of a value. | ||
JamieMagee marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #### Description | ||
|
|
||
| This happens when the Bluetooth connection to the bike has dropped. The most common causes are the bike going to sleep, being out of range, or another app holding the Bluetooth connection. | ||
|
|
||
| #### Resolution | ||
|
|
||
| To resolve this issue, try the following steps: | ||
|
|
||
| 1. Wake the bike by pedaling or pressing the power button. | ||
| 2. Check whether the Specialized Mission Control app (or another BLE client) has an active connection. Only one client can connect at a time. | ||
| 3. Try restarting the integration from {% my integrations title="**Settings** > **Devices & services**" %}. | ||
|
|
||
| ### Pairing PIN not accepted | ||
|
|
||
| #### Symptom: The pairing PIN is rejected during setup | ||
|
|
||
| When you enter the PIN shown on the bike's TCU screen, the integration rejects it or pairing fails. | ||
|
|
||
| #### Description | ||
|
|
||
| The bike may already be paired with another device, or your Bluetooth backend may not support programmatic PIN entry. | ||
|
|
||
| #### Resolution | ||
|
|
||
| To resolve this issue, try the following steps: | ||
|
|
||
| 1. On the bike's TCU, reset the BLE pairing and try setting up the integration again. | ||
| 2. If you don't see a PIN prompt on the bike's screen, it may still be paired with another device. Clear old pairings first. | ||
| 3. If the PIN is still not accepted, pair the bike through your operating system's Bluetooth settings first, then set up the integration without entering a PIN. | ||
|
|
||
| ## Removing the integration | ||
|
|
||
| This integration follows standard integration removal. | ||
|
|
||
| {% include integrations/remove_device_service.md %} | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.