feat: make --device flag optional with 'any' default
When --device is omitted or set to 0, the bridge listens to all broadcasting ANT+ trainers instead of filtering by a specific device. The actual transmitting device ID is shown in data logs, allowing users to discover and then filter specific trainers. Also fix vendorID/productID not being assigned to config struct which caused ListenForTrainer to receive 0 for both values.
This commit is contained in:
parent
19e4e78c75
commit
7f52f0ff68
44
README.md
44
README.md
@ -119,13 +119,13 @@ The binary is built to `bin/bridge`.
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Use defaults (device 3001)
|
||||
# Listen to all trainers (default)
|
||||
sudo ./bin/bridge
|
||||
|
||||
# Custom trainer device
|
||||
# Filter for a specific trainer
|
||||
sudo ./bin/bridge --device 0xbb9
|
||||
|
||||
# Custom vendor/product IDs
|
||||
# Custom vendor/product IDs with specific device
|
||||
sudo ./bin/bridge --vendor 0x0fcf --product 0x1008 --device 3001
|
||||
```
|
||||
|
||||
@ -135,14 +135,14 @@ sudo ./bin/bridge --vendor 0x0fcf --product 0x1008 --device 3001
|
||||
|------|---------|-------------|
|
||||
| `--vendor` | `0x0fcf` | USB vendor ID (hex or decimal, e.g. `0x0fcf` or `4047`) |
|
||||
| `--product` | `0x1008` | USB product ID (hex or decimal) |
|
||||
| `--device` | `3001` | ANT+ device number (hex or decimal, e.g. `3001` or `0xbb9`) |
|
||||
| `--device` | `0 (any)` | ANT+ device number (hex or decimal). Use 0 or omit to listen to all devices |
|
||||
| `--help` | | Show help |
|
||||
| `--version` | | Show version info |
|
||||
|
||||
## Finding your trainer's ANT+ device number
|
||||
|
||||
Most ANT+ cycling power trainers use device number `3001` (decimal) or `0xbb9` (hex). If that works, you can use the
|
||||
bridge with default settings.
|
||||
The bridge listens to all broadcasting devices by default. When multiple ANT+ trainers are nearby, each will appear in the
|
||||
log output as `ant: <device_id>: power: ...`. Use `--device <id>` to filter for a specific trainer.
|
||||
|
||||
If you're unsure of your trainer's device number, you can discover it using another ANT+ device (e.g., a Garmin Edge
|
||||
head unit). Connect the Garmin to your trainer and look for the device number in the ANT+ sensor list.
|
||||
@ -179,11 +179,14 @@ Your trainer's power and cadence data should now be available in the app.
|
||||
|
||||
```
|
||||
2026-05-26 11:00:34 ANT Bridge abc1234 built 2026-05-26T11:00:00
|
||||
2026-05-26 11:00:34 vendor: 0x0fcf/4047
|
||||
2026-05-26 11:00:34 product: 0x1008/4104
|
||||
2026-05-26 11:00:34 device: 0xbb9/3001
|
||||
2026-05-26 11:00:34 BLE advertising...
|
||||
2026-05-26 11:00:34 bt: watts: 150 rpm: 80 completedRevs: 1234 lastRevTime: 4890
|
||||
2026-05-26 11:00:34 usb: vendor: 0x0fcf/4047
|
||||
2026-05-26 11:00:34 usb: product: 0x1008/4104
|
||||
2026-05-26 11:00:34 ant: device: any
|
||||
2026-05-26 11:00:34 ant: device opened
|
||||
2026-05-26 11:00:34 bt: BLE advertising...
|
||||
2026-05-26 11:00:34 ant: scan mode started
|
||||
2026-05-26 11:00:34 ant: listening...
|
||||
2026-05-26 11:00:35 ant: 3001: power: 150W cadence: 80 rpm
|
||||
```
|
||||
|
||||
The bridge logs a lot of output during normal operation — this is expected and helpful for debugging during this early
|
||||
@ -191,9 +194,14 @@ stage of development.
|
||||
|
||||
Key log lines:
|
||||
- `ANT Bridge ...` — Startup message with version and build time
|
||||
- `vendor: ...` / `product: ...` / `device: ...` — Configuration being used
|
||||
- `BLE advertising...` — BLE service is ready and visible to other devices
|
||||
- `bt: watts: ...` — Power and cadence data being broadcast
|
||||
- `usb: vendor: ...` / `usb: product: ...` — USB dongle configuration
|
||||
- `ant: device: ...` — ANT+ device filter (or `any` if listening to all devices)
|
||||
- `ant: device opened` — USB dongle opened successfully
|
||||
- `bt: BLE advertising...` — BLE service is ready and visible to other devices
|
||||
- `ant: scan mode started` / `ant: listening...` — ANT+ receiver is active
|
||||
- `ant: <id>: power: ...` — Power/cadence data with transmitting device ID
|
||||
- `bt: watts: ...` — Power/cadence data being broadcast over BLE
|
||||
- `ant: received msg from ignored device ...` — Message from non-matching device (when `--device` is specified)
|
||||
- `hciconfig ... failed` — Bluetooth adapter reset warnings (usually harmless)
|
||||
|
||||
## Development
|
||||
@ -228,12 +236,12 @@ make clean # Remove build artifacts
|
||||
### No data from trainer
|
||||
|
||||
- Make sure the trainer is turned on and broadcasting
|
||||
- Use another device (e.g. Garmin Edge) to verify it is broadcasting. This also provides a way
|
||||
to get the device id.
|
||||
- Use another device (e.g. Garmin Edge) to verify it is broadcasting. This also provides a way
|
||||
to get the device id.
|
||||
- The bridge listens to all devices by default. If multiple trainers are broadcasting, use
|
||||
`--device <id>` to filter for a specific one
|
||||
- Make sure the dongle is close enough to the trainer (within 1-2 meters)
|
||||
- Verify the device number is correct (try `--device 3001`)
|
||||
- Check the log output for the `listening...` message
|
||||
- Try a different device number if available
|
||||
|
||||
### BLE connection drops
|
||||
|
||||
|
||||
@ -56,8 +56,8 @@ func ListenForTrainer(vendorId uint16, productId uint16, deviceNumber uint32,
|
||||
|
||||
logMsg("ant: listening...")
|
||||
for msg := range msgs {
|
||||
if msg.DeviceNumber() != deviceNumber {
|
||||
logPrintf("Received msg from ignored ant+ device %v\n", msg.DeviceNumber())
|
||||
if deviceNumber != 0 && msg.DeviceNumber() != deviceNumber {
|
||||
logPrintf("ant: received msg from ignored device %v\n", msg.DeviceNumber())
|
||||
continue
|
||||
}
|
||||
//fmt.Printf("raw msg: device type=0x%02x device number=%d content=%x\n",
|
||||
|
||||
@ -52,19 +52,26 @@ This allows these trainers to be used with modern devices that don't support ANT
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid --product %q: %w", c.product, err)
|
||||
}
|
||||
deviceNumber, err := parseHex(c.device, 32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid --device %q: %w", c.device, err)
|
||||
c.vendorID = uint64(vendorID)
|
||||
c.productID = uint64(productID)
|
||||
if c.device != "" {
|
||||
deviceNumber, err := parseHex(c.device, 32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid --device %q: %w", c.device, err)
|
||||
}
|
||||
c.deviceNumber = uint32(deviceNumber)
|
||||
}
|
||||
|
||||
c.vendorID = vendorID
|
||||
c.productID = productID
|
||||
c.deviceNumber = uint32(deviceNumber)
|
||||
deviceNumber := c.deviceNumber
|
||||
|
||||
logMsgf("ANT Bridge %s built %s", Version, BuildTime)
|
||||
logMsgf("usb: vendor: 0x%04x/%d", vendorID, vendorID)
|
||||
logMsgf("usb: product: 0x%04x/%d", productID, productID)
|
||||
logMsgf("ant: device: 0x%03x/%d", deviceNumber, deviceNumber)
|
||||
if deviceNumber == 0 {
|
||||
logMsgf("ant: device: any")
|
||||
} else {
|
||||
logMsgf("ant: device: 0x%03x/%d", deviceNumber, deviceNumber)
|
||||
}
|
||||
|
||||
if err := exec.Command("hciconfig", "hci0", "down").Run(); err != nil {
|
||||
logPrintf("bt: hciconfig down failed: %v\n", err)
|
||||
@ -83,7 +90,7 @@ This allows these trainers to be used with modern devices that don't support ANT
|
||||
|
||||
rootCmd.Flags().String("vendor", "0x0fcf", "USB vendor ID (hex, e.g. 0x0fcf)")
|
||||
rootCmd.Flags().String("product", "0x1008", "USB product ID (hex, e.g. 0x1008)")
|
||||
rootCmd.Flags().String("device", "3001", "ANT+ device number (hex or decimal, e.g. 3001 or 0xbb9)")
|
||||
rootCmd.Flags().String("device", "", "ANT+ device number (hex or decimal). Use 0 or omit to listen to all devices")
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user