Skip to content

Commit 9ddb698

Browse files
malysclaude
andcommitted
docs: record the DAB reversal and the glass control change
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 550ce9b commit 9ddb698

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,35 @@ All notable changes to this project are documented here. Format follows
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- **A rule can put the tuner on a band, DAB included.** `SELECT_RADIO_BAND` is the answer to
12+
the one gap the radio work left: "tune the radio" takes a frequency a driver typed, and a DAB
13+
service is addressed by an ensemble and service id, so there was nothing to type and no way
14+
to ask for DAB. The action guesses no transaction code — the vendor service exposes no
15+
band-only call that anyone here has observed, and a wrong code on a vehicle binder does
16+
something unknown to a car. It composes calls that are already proven instead: read the
17+
current band from `RadioBean`, then `tune` into the requested one, since `tune` carries the
18+
band as its first argument. It lands on the station this car was last heard on for that band,
19+
and when it has never been there it steps to the first station the tuner lists rather than
20+
leaving the driver on an empty frequency. An unreadable current band sends nothing at all.
21+
22+
### Changed
23+
24+
- **The window actions ask to open or close, instead of carrying a raw command.** They used to
25+
take a number in 0..7 — the vendor service's own command range, which nothing in the app or
26+
the car explains to the person writing the rule. An on-vehicle capture showed what that
27+
costs: a rule asking for `7` ran five times, was reported as applied five times, and left the
28+
driver's window fully open throughout, because the service accepts a command it does not
29+
implement and drops it. Closed and open are the only two states the glass can be asked for,
30+
so those are the two the editor now offers.
31+
Which raw command reaches each is a property of the *car*, established by the window probe and
32+
stored per car, so it stays out of the catalogue and out of saved rules — a rule exported from
33+
one car must not carry that car's command numbers.
34+
35+
- **"Windows" is now "All windows".** It commands four windows at once, and the bare plural read
36+
as the family of window actions rather than the one that moves them together.
37+
938
## [1.10.0] - 2026-08-29
1039

1140
### Fixed

‎docs/radio-action-gap.md‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ a missing service call, is the actual gap.
3232
| A | Pause / stop the radio | **add** — `PAUSE_RADIO` | `srcPauseRadio` is implemented and unreachable. `MEDIA_CONTROL` is not a substitute: it addresses whichever source owns the audio, so it silences Bluetooth when Bluetooth is playing. "Silence the tuner" was not expressible. |
3333
| B | Explicit radio play/pause toggle on readable state | **add** — `RADIO_PLAY_PAUSE` | One shortcut for a driver who wants the tuner specifically, whatever the current source. Built on `isPlaying()` (`RadioBean.state`), because `AudioManager.isMusicActive` is **false while the radio plays** — a toggle driven by it would send "play" to a playing radio forever. Unknown state fails closed (see below). |
3434
| C | Open the radio screen | **add, gated** — `OPEN_RADIO_SCREEN` | `startRadioActivity` is implemented and unreachable. It is the one radio action that is not audio-only: throwing a full-screen app in front of a driver at speed is a distraction, so it takes the standstill gate and is refused when speed is unreadable. |
35-
| D | Select a band | **reject** | The binding contract exposes no band-only call. `tune` takes `(band, frequencyKhz)` together, so a band action would have to invent a frequency — and the one it invented would be the station the driver did not ask for. FM/AM band selection is already carried by `TUNE_RADIO`, which infers the band from what was typed. |
36-
| E | Select a DAB service | **reject** | A DAB service is addressed by ensemble id + service id, not by a frequency, and neither is a stable identifier a driver could enter or a rule could store across a re-scan. No on-vehicle evidence establishes a portable contract. DAB stays reachable through `RADIO_NEXT_STATION` / `RADIO_PREV_STATION`, which step the tuner's own list on whatever band it is on — band 4 in `MediaConstants` is DAB, and the launcher's own skip is this same call. |
35+
| D | Select a band | **added** (2026-08-29, reversed) | Originally rejected because the binding contract exposes no band-only call. The owner asked for DAB support anyway, and the rejection turned out to be answering the wrong question: a band action does not need a band-only *call*, because `tune(band, frequencyKhz)` already carries the band as its first argument. `SELECT_RADIO_BAND` composes what is established — read the current band from `RadioBean`, tune into the requested one — and guesses no transaction code. The frequency it lands on is the station this car was last heard on for that band (`RadioBandMemory`), or the band floor followed by one `nextStation()` when it has never been there, so it does not strand the driver on an empty frequency. |
36+
| E | Select a DAB service | **reject** (unchanged) | A DAB service is addressed by ensemble id + service id, not by a frequency, and neither is a stable identifier a driver could enter or a rule could store across a re-scan. No on-vehicle evidence establishes a portable contract. DAB is now reachable as a **band** (candidate D) and stepped through with `RADIO_NEXT_STATION` / `RADIO_PREV_STATION`; what stays out is selecting one named service directly. A DAB *block* is a real frequency in Band III, which is what a band switch tunes; a DAB *service* is not. |
3737
| F | Restore the last audible radio state at ignition | **already covered** | Composition, not a new action: an ignition trigger plus `PLAY_RADIO`, whose `srcPlayRadio` resumes the last station by itself. A persistent service that remembered and re-asserted state would be a background watchdog the app does not have and does not want. |
3838
| G | Radio artwork caching, station metadata display | **reject as an action** | Presentation, not automation. A rule cannot usefully "cache artwork"; a screen can show it. If it is ever wanted it belongs to an app's UI, reading `RadioBean`, not to the action catalogue. |
3939
| H | Replace or patch the OEM radio APK (the DAB+ fix's strategy) | **reject** | Out of scope by the ticket and by the suite's boundary: EVSuite talks to the vendor services the car ships. It does not swap the car's applications, and the upstream fix carries no license that would permit reuse anyway. |
@@ -55,6 +55,14 @@ a missing service call, is the actual gap.
5555
`ActionCompatibility` refuses the action there before it is attempted, and the editor does
5656
not offer it.
5757

58+
## Reversal, 2026-08-29
59+
60+
Candidate D was reopened at the owner's request after an on-vehicle diagnostic (SWI68). The
61+
original rejection assumed a band action required a band-only transaction, and that assumption
62+
was wrong: `tune` takes the band as an argument, so the band is reachable through a call that
63+
was already proven. The rejection of candidate E stands unchanged — a DAB service still has no
64+
identifier stable across a re-scan, and none was guessed.
65+
5866
## On-vehicle evidence
5967

6068
_(pending — CR-020 requires a run. Record, per firmware: `SaicRadio.isAvailable`, whether

0 commit comments

Comments
 (0)