Skip to content

Commit 13cfcde

Browse files
eriedclaude
andcommitted
feat(inmotion-v1): show the real model name, write NO_RESPONSE for reliable commands
Two follow-ups now that the V8S connects reliably (MTU-wedge fix confirmed working): 1. Model name showed generic "InMotion V1 (serial)" instead of "V8S". The model WAS detected from the BLE name ("V8S-81E30005" -> V8S) but the display only used the model decoded from the slow-info bytes, which the V8S doesn't carry, so it fell back to the generic label. Now notifyConnectingTo emits the name-detected model immediately, and the slow-info path falls back to it when the bytes carry no model id. 2. Switch InMotion V1 writes to WRITE_TYPE_NO_RESPONSE (ATT 0x52) - the write type EUC World uses for all data writes. With write-with-response, an ack lagging past the ~250 ms poll interval gets the next write rejected code 201, which can drop a one-shot command like a legal-mode / speed-limit change. No-response frees the GATT immediately so writes never collide. Safe now that the fatal-201 cause (the requestMtu wedge) is fixed; the earlier NO_RESPONSE build failed on that wedge, not the write type. Branch also merges origin/next-version (trip map style, studio replay panes, i18n, dropbox conflict fix). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GADLyChheAoMX9dQbRgRnH
1 parent 3bd5cf2 commit 13cfcde

2 files changed

Lines changed: 25 additions & 11 deletions

File tree

app/src/main/java/com/eried/eucplanet/ble/InMotionV1Adapter.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ class InMotionV1Adapter @Inject constructor() : WheelAdapter {
6666
detectedModel = deviceName?.let { InMotionV1Model.fromReportedName(it) }
6767
streamStarted = false
6868
authPollTick = 0
69-
return null
69+
// Surface the model straight from the BLE name (e.g. "V8S-81E30005" ->
70+
// V8S) so the UI shows the real model immediately, without waiting for -
71+
// or depending on - a model id in the slow-info bytes (the V8S carries
72+
// none). Returns null when the name isn't a recognised V1 model.
73+
return detectedModel?.let { DecodeResult.ModelName(it.displayName, it) }
7074
}
7175

7276
/**
@@ -296,10 +300,15 @@ class InMotionV1Adapter @Inject constructor() : WheelAdapter {
296300
val info = InMotionV1Parser.parseSlowInfo(payload) ?: return emptyList()
297301
streamStarted = true
298302
if (info.model != null) detectedModel = info.model
303+
// Prefer the model decoded from the slow-info bytes, but fall
304+
// back to the one detected from the BLE name (V8S carries no
305+
// model id in slow-info, so without this it showed as a generic
306+
// "InMotion V1 (serial)" despite the name saying V8S).
307+
val model = info.model ?: detectedModel
299308
val out = mutableListOf<DecodeResult>()
300309
out += DecodeResult.ModelName(
301-
info.model?.displayName ?: "InMotion V1 (${info.serial})",
302-
info.model
310+
model?.displayName ?: "InMotion V1 (${info.serial})",
311+
model
303312
)
304313
out += DecodeResult.Firmware(
305314
display = "FW ${info.firmware}",

app/src/main/java/com/eried/eucplanet/ble/WheelAdapter.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,19 @@ data class BleProfile(
8484
// NOT the 0xFFE0 notify service. Without this the write char lookup
8585
// returns null on service discovery and the connect is torn down,
8686
// so no InMotion V1 wheel (V5 / V8 / V10 / V10F / L6) could connect.
87-
writeServiceUuid = UUID.fromString("0000ffe5-0000-1000-8000-00805f9b34fb")
88-
// Keep the default WRITE_TYPE_DEFAULT (write-with-response). The
89-
// real cause of the code-201 write rejections was the requestMtu(512)
90-
// wedging the GATT (see BleConnectionManager - MTU is now skipped for
91-
// this family), NOT the write type. NO_RESPONSE was tried and the
92-
// build regressed to never connecting, so it stays on the default.
93-
// (EUC World does use no-response writes; that can be revisited as an
94-
// isolated change once the MTU-wedge fix is confirmed.)
87+
writeServiceUuid = UUID.fromString("0000ffe5-0000-1000-8000-00805f9b34fb"),
88+
// NO_RESPONSE (Write Command, ATT opcode 0x52) - the write type EUC
89+
// World uses for ALL its data writes. With WRITE_TYPE_DEFAULT
90+
// (with-response) each write stays "busy" until the wheel acks it, and
91+
// when that ack lags past the ~250 ms poll interval the next write is
92+
// rejected code 201, occasionally dropping a one-shot command (e.g. a
93+
// legal-mode / speed-limit change). No-response frees the GATT
94+
// immediately so writes never collide. This is safe now that the real
95+
// cause of the FATAL 201 storm - the requestMtu(512) wedge - is fixed
96+
// (MTU is skipped for this family in BleConnectionManager); NO_RESPONSE
97+
// only removes the residual collisions. The earlier NO_RESPONSE build
98+
// "never connected" because of that MTU wedge, not the write type.
99+
writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
95100
)
96101
}
97102
}

0 commit comments

Comments
 (0)