01 · Verdict

Rada's £313 box is a microcontroller on a cable. We can be that microcontroller.

Rada's Networking Upgrade Pack plugs into the valve's own control-panel port and translates Modbus into whatever the valve already speaks. The valve, not the box, does the work. Three ways to talk to it ourselves, from £2 to £8, ordered by how little wiring they need.

£2Route 1: an ESP32 speaking the valve's Bluetooth
£8Route 2: ESP32 spliced into the panel cable
£2Route 3: IR injection inside the control panel
20 minof checks tonight decide which one

What the documents established

  • The valve is the brain. The wall panel is a dumb infrared sensor plate on a 3 m "data cable" (6 m max, 9 V DC feed to the panel). Every command in Rada's Modbus map (valve on/off/pause, outlet 1 and 2 on/off, setpoint, run time, live temperature, error codes) is something the valve executes when asked over that cable.
  • The Networking Pack is a man-in-the-middle. Its ports are labelled ENG (control panel), VLV (valve), NET (RS485 Modbus), RLY, PIR, KS. Panel and valve plug into it; it relays and injects. Valves made after July 2014 need no PCB change, so the cable protocol on your valve already accepts a third party.
  • Your valve is the Bluetooth generation. The dual-shower manual for part 1.1653.030 says a Bluetooth LE app is required to configure it, default PIN 2502. Kohler Mira's other BLE shower, the Mira Mode, has a fully reverse-engineered protocol: same company, same years, same "dual outlet" product shape, and its BLE command set includes outlet on/off and temperature.
  • The Rada app itself has no start button, only settings, so nobody has bothered to look. The valve firmware may still implement the control command, because the Mira stack does. That is the cheapest thing to test and it is where I would start.
WALL CONTROL PANEL IR proximity: flow, up, down LEDs · magnetic disable key 9 V DC from the valve in the bathroom "data cable" · 3 m (6 m max) · power + serial data DIGITAL MIXING VALVE stepper mixer · thermistor · 2 outlet solenoids control PCB · Bluetooth LE radio holds setpoint, run time, limits 12 V DC SELV from PSU loft / cupboard, ≤ 3 m from panel PSU 12 V 45 W 3 A fused spur Rada Networking Pack £313 · ENG ⇄ VLV · NET = Modbus ROUTE 1 · Bluetooth LE ESP32 pairs like the app · £2 ROUTE 2 · Cable tap ESP32 where Rada's box goes · £8 ROUTE 3 · Electronic hand IR mirror inside the panel · £2
DWG 01
The Rada Sense system and where each route attaches
REV A
2026-09-07
Route 2 attaches exactly where Rada's own box does, so it is guaranteed to be possible; it just needs the cable protocol read first. Route 1 needs no wiring at all if the valve's Bluetooth accepts the control command. Route 3 never touches a protocol.

Recommendation

  1. Tonight: the checks in section 2. They need a phone, a screwdriver and a multimeter, and they tell us which route is open.
  2. If the valve advertises the Mira BLE service: Route 1. An ESP32 in the airing cupboard, no wiring, done in an evening once the pairing exchange has been captured from the app.
  3. Otherwise: Route 2. A £5 logic analyser on the panel cable for one evening, then the ESP32 splice board. This is the certain route; Rada's product proves the port accepts commands.
  4. Route 3 only if you want on/off this weekend without waiting for a capture. It is invisible, reliable, and can be replaced by 1 or 2 later without changing anything in Home Assistant.
02 · Tonight's 20 minutes

Four checks that pick the route

No soldering, nothing disconnected under load. Each check answers one question; send me the results and photos and I will write the firmware against them.

  1. Bluetooth scan (5 min, phone only).

    Install nRF Connect (Nordic, free) on your phone, stand near the valve and scan. Find the device whose name matches the alias in the Rada app (or anything from Kohler / Mira / Rada). Tap it, connect, and screenshot the service list. What we want to see is a service containing bccb0002-ca66-11e5-88a4-0002a5d5c51b (write) and bccb0003-… (notify). If those are there, it is the Mira Mode stack and Route 1 is on. Also note the MAC address; the ESP config needs it.

  2. Valve label (1 min).

    Photo of the label on the mixing valve enclosure: part number, "Wk/Yr" manufacture date, and the PSU part number. It confirms the generation.

  3. Panel cable at the valve (10 min, power ON, then OFF).

    Open the valve's electronics cover (screws, no seal to break; it is 12 V SELV in there). Photograph the connector where the control-panel cable lands, close enough to read any silkscreen, and the PCB around it. Then with the multimeter on DC volts, black probe on the PSU's 0 V, read each pin of the panel connector with the panel idle. Write the numbers down in pin order. The pattern tells us the bus: one pin near 9 V and one at 0 V are power; a pin sitting at about 3.3 V or 5 V is a TTL UART line; a pair sitting at about 2.5 V and 2.5 V with a small difference is RS485; a pin at 9–12 V that dips when you wave at the panel is a single-wire bus.

  4. Count the cores (2 min, power OFF).

    How many wires in the panel cable, and their colours. Three cores is power, ground, one data line. Four is power, ground, two data (either a UART pair TX/RX or an RS485 pair). Five or more usually means separate LED or sensor lines and a simpler panel.

Two things not to do

Do not unplug the panel cable with the PSU live; the valve's own protection may latch an error that needs a power cycle to clear, and we lose an hour wondering why. And do not probe the PSU's mains side; everything we need is on the 12 V side of it.

What the answers decide

FindingRouteNext step
Mira service UUIDs present1Capture the app's pairing exchange (section 3), then flash the BLE ESP32.
BLE present but different UUIDs1 or 2Decompile the Rada app (section 3) to read its command table; if it only carries settings, go to Route 2.
Panel cable has a 3.3 V or 5 V data line, or an RS485 pair2Logic-analyser capture (section 4), then the splice board.
Panel cable is 9 V + ground + one odd line2 or 3Capture it anyway; a single-wire bus is still just serial. Route 3 if it turns out to be analogue.
03 · Route 1 · Bluetooth LE

Talk to the valve the way its own app does

The Mira Mode protocol is documented in the python-miramode project. It is a tiny framed protocol with a 16-bit CRC, a client id you get by pairing once, and one command that switches both outlets and sets the temperature. If the Sense valve shares the stack, an ESP32-C3 in the cupboard is the whole build.

The protocol, as known from Mira Mode

ItemValueNotes
Write characteristicbccb0002-ca66-11e5-88a4-0002a5d5c51bWrite without response, 20-byte chunks
Notify characteristicbccb0003-ca66-11e5-88a4-0002a5d5c51bResponses arrive here, possibly fragmented
Framepayload + CRC16(payload + client_id)CRC-CCITT, poly 0x1021, init 0xFFFF; client_id is 4 bytes big-endian and is not transmitted, only mixed into the CRC. That is the authentication.
Pairing[0x00, 0xEB, 24, id(4), name(20)]CRC'd with the magic id 0x54D2EE63. Mira enters pairing by holding the outlet button 5 s; Rada uses PIN 2502 in the app instead, so the Sense pairing frame will differ and must be captured.
Client slotnotify[0] − 0x40Returned after pairing; first byte of every later command.
Control outlets[slot, 0x87, 0x05, timer, tempHi, tempLo, out1, out2]timer 1 = running, 3 = paused; temperature ×10 big-endian; outlet 0x64 = on, 0x00 = off
Request state[slot, 0x07, 0x00]Reply (10 bytes): timer, target °C×10, actual °C×10, outlet1, outlet2, seconds remaining, counter
CONTROL FRAME · 10 bytes on the wire slotfrom pairing 0x87control 0x05length timer1 run · 3 pause temp hi°C × 10 temp lobig-endian outlet 10x64 on outlet 20x00 off CRC16 hi · loover payload + client id payload (8 bytes) payload bytes client id (4 bytes, secret) CRC-CCITT (0x1021, init 0xFFFF) is computed over this 12-byte sequence; only the 2 CRC bytes are sent. Without the client id the valve ignores the frame. example: 38.0 °C= 0x017C
DWG 02
Mira Mode control frame (expected on Rada Sense; confirm from capture)
REV A
2026-09-07

Capture the Rada app talking to the valve

Two ways, both using your own phone and the app you already have. The first gets the pairing frames and the client id; the second gets the whole command table.

A · Bluetooth HCI snoop log

  1. On the phone: Settings → Developer options → enable Bluetooth HCI snoop log. Toggle Bluetooth off and on.
  2. Open the Rada Sense app, connect to the valve with the PIN, change the flow time by one second and save, read the usage data, disconnect.
  3. Pull the log with adb from the Pi (the phone is already authorised there) and open it in Wireshark with the filter btatt. Every write to bccb0002 is a frame; the first ones after connecting are the PIN/pairing exchange.
on DECS · pull the HCI log

B · Read the app's own code

  1. Pull the installed APK from the phone: adb shell pm path com.kohler.radasense then adb pull <path> rada.apk.
  2. Open it in jadx-gui on the PC. Search for bccb0002, 0x1021 or 2502. The class that builds frames lists every command byte the app knows, including any it never shows a button for.
  3. If a 0x87-style control command exists there, or the frame builder is byte-for-byte the Mira one, Route 1 is confirmed before we power anything.

The ESP32 build

One ESP32-C3 on a USB adapter within about 8 m of the valve. ESPHome's BLE client connects, writes frames, and listens for the state notification. The CRC and frame builder are in the lambda, so once the capture gives us slot and client id they are two substitutions.

shower-ble.yaml · ESPHome
If the Pi is within Bluetooth range of the valve

You can skip the ESP entirely for the first test: pip install python-miramode on DECS, run devices-list, then device-state with the slot and client id from the capture. If the valve answers with a sensible temperature, the protocol is confirmed and the ESP build above is a formality.

04 · Route 2 · Cable tap

Sit where Rada's box sits

The panel cable carries power to the panel and serial data both ways. Rada's box proves the valve will take commands from a third device on that port. The job is to read the traffic once, then build a £8 board that relays the panel and injects our own frames.

Step 1 · Identify the bus (from tonight's multimeter readings)

Idle reading on a data pinBusHow to listen
3.3 V or 5 V steady, dips during trafficTTL UART, one line per direction (or one shared line)Logic analyser straight on the pins, ground to 0 V. ESP32 UART RX pins direct (5 V needs a 10 k / 20 k divider).
Two pins both around 2–3 V, differing by 0.2–0.5 VRS485 pair (A/B)Logic analyser across the pair via a MAX3485 module; the ESP uses one MAX3485 per side.
9–12 V that dips briefly when the panel is usedSingle-wire bus, power and data on one coreLogic analyser via a 10 k / 3.3 k divider to 3.3 V logic; the ESP needs an open-collector driver to inject.
Pins that change slowly (0–3 V analogue) when you waveNot a bus; the panel sends raw sensor levelsRoute 3, or Route 1.

Step 2 · Capture one evening of traffic

  1. Wire the logic analyser.

    A £5 8-channel 24 MHz USB analyser (the Saleae-clone) with PulseView. GND to the PSU 0 V, one channel per data pin. For RS485, the A line alone against ground decodes fine at this speed.

  2. Record with the panel idle for 60 s.

    Most of these buses poll: the valve asks the panel for its sensor state every 50–200 ms and the panel replies. That gives baud rate, framing and the idle poll pattern before you touch anything.

  3. Record one action each.

    Hand at the flow sensor (on), again (off), up once, down once, the magnetic cleaning key on and off. Name each capture.

  4. Decode.

    PulseView's UART decoder with the baud guessed from the shortest pulse (1 / width). 9600, 19200 and 38400 are the likely ones; Rada's Modbus side runs 9600 8N1, and firmware writers rarely use two speeds. Look for a repeating header byte, a length, and two trailing bytes that change with every frame (a CRC; try 0x1021 init 0xFFFF first, it is the one Kohler Mira used on Bluetooth).

  5. Find the command.

    Compare the frames sent panel→valve during "hand at flow sensor" with the idle ones. Either the panel sends an event frame ("flow touched") or the valve polls and the panel's reply has a bit set. Either way, replaying that frame from the ESP is our on switch. Temperature up/down the same way.

Step 3 · The splice board

PANEL via its cable VALVE panel port SPLICE BOARD · 60 × 40 mm perfboard, in the valve cupboard XCVR A MAX3485 (RS485) or divider + direct (TTL) faces the panel XCVR B MAX3485 (RS485) or direct (TTL) faces the valve ESP32-C3 GPIO5 RX-AGPIO4 TX-AGPIO1 DE-A RX-B GPIO20TX-B GPIO21DE-B GPIO0 firmware: relay A⇄B, log, inject data data 9 V feed and 0 V pass straight through, uncut buck 9 V → 5 V (MP1584) 5 V to the ESP (≈ 0.4 W; the panel feed is rated 5 W) If the multimeter shows a TTL bus, XCVR A/B are just two resistors each; the ESP's UARTs connect almost directly.
DWG 03
Cable-tap splice board (relay + inject), both bus variants
REV A
2026-09-07
The ESP relays every byte between panel and valve so the panel keeps working exactly as before. When Home Assistant asks, the ESP sends the captured "flow on" frame to the valve itself. This is the same topology as Rada's box; ours costs the price of two transceiver modules.

Firmware · sniffer first, relay second

The same sketch does both jobs. On its own it logs both directions with timestamps over USB so you can confirm the decode from PulseView against live traffic. With RELAY on, it passes bytes through and accepts inject <hex> on the USB console or from Home Assistant. Once the frames are known this becomes a proper ESPHome component; the sketch is for the discovery week.

shower-tap.ino · ESP32-C3 · Arduino
Why relay byte-by-byte works

At 9600 baud a byte lasts about 1 ms and the ESP adds roughly 0.1 ms of delay in each direction, well inside any serial timeout. If the bus turns out to be a single shared line rather than two directions, the sketch changes to one UART with the TX driven open-collector, and the injection is a matter of waiting for a quiet gap. Both cases are a few lines once the capture exists.

05 · Route 3 · Electronic hand

A hand the panel cannot tell from yours, hidden inside it

The panel's three controls are infrared proximity sensors: an emitter flashes, a detector looks for the reflection off your hand. A phototransistor watching the emitter and an IR LED aimed at the detector, switched on together by the ESP, is a reflection with the panel's own timing. It needs no protocol and no capture.

INSIDE THE PANEL · one sensor position panel IR emitter pulsed by panel MCU panel IR detector read by panel MCU our parts, glued in the shell Q1 phototransistor D1 IR LED 940 nm sees pulses "reflection" Q2 BC337 R2 47 Ω R1 10 k ESP32-C3 GPIO4 → FLOW enableGPIO5 → UP enableGPIO6 → DOWN enableGND 3.3 V only while enabled = powers Q1/Q2/D1 Three copies of Q1/Q2/D1/R1/R2, one per sensor. ESP in the ceiling void or behind the panel; four thin wires (3 enables + GND) through the panel's own cable hole. Enable pulse: 400 ms for a "touch", the same as a hand wave. WHY IT WORKS detector only trusts light that flashes when the emitter does. Q1 copies that timing exactly.
DWG 04
Electronic hand: emitter-synchronised IR injection, one channel
REV A
2026-09-07
A plain IR LED left on would be cancelled by the panel's ambient-light rejection. Because Q1 only turns D1 on during the panel's own emitter pulses, the detector sees exactly what a hand at 5 cm produces. The ESP just powers the little circuit for 400 ms.

Fitting it

  1. Take the panel off the wall (two screws behind the cover; silicone bead on the back). Photograph the PCB. Each sensor position has an emitter and a detector, usually a black-domed pair or a single reflective module.
  2. Q1 goes beside the emitter with a dab of hot glue, D1 beside the detector pointing at it, both inside the front shell so nothing shows.
  3. Tune with the multimeter on the panel's detector output if it is accessible, otherwise empirically: start with R2 at 220 Ω (dim) and reduce until the panel reacts every time and never reacts with the enable off.
  4. Wires out through the existing cable hole to the ESP. The ESP can share the panel's 9 V feed through a tiny buck, or take its own USB adapter in the ceiling void.
What it cannot do

On/off, warmer, cooler: the same three things a person can do at the panel. No temperature readback, no error codes, no "is it running" beyond the state Home Assistant assumes. That is why it is the fallback and not the plan.

06 · Home Assistant & voice

“Hey Google, turn on the shower”

Whichever route wins, Home Assistant sees the same three entities: two outlet switches and a temperature number. The voice layer, the safety timers and the presence tie-in are written once, here.

/config/packages/shower.yaml

Voice phrases that will work

SayHappensVia
"Hey Google, turn on the shower"Overhead outlet on at the stored temperature; auto-off timer startsswitch.shower → Google Assistant
"Hey Google, turn off the shower"Both outlets offsame
"Hey Google, shower in five minutes"A Google routine that waits then turns the switch onGoogle routine
"Hey Google, make the shower warmer"Number entity up 1 °C, still capped at the valve's 41 °CGoogle routine → HA script
Local, no cloudSame phrases through Assist once the Speech-to-Phrase satellite existsHA Assist
07 · Parts & tools

Everything, for all three routes

Order the discovery kit now; it covers whichever route the checks pick and still comes to less than a tenth of Rada's box.

ItemFor£Note
ESP32-C3 Super Mini × 2All routes (one spare)4.00Same board as the presence nodes; same secrets, same dashboard on the Pi.
USB logic analyser, 8 ch 24 MHzRoute 2 capture5.00"24MHz 8CH USB logic analyzer"; PulseView is free.
MAX3485 RS485 modules × 2Route 2 if the bus is RS4852.003.3 V modules, not MAX485 (5 V).
MP1584 buck moduleRoute 2 / 3 power from the 9 V feed0.80Set to 5.0 V before connecting.
IR LED 940 nm × 3, phototransistor × 3, BC337 × 3, resistorsRoute 31.50Any "IR emitter + receiver pair" listing.
Dupont leads, perfboard, heat-shrinkAll2.00
nRF Connect (phone app), Wireshark, jadx, PulseViewDiscovery0All free.
Total≈ 15versus £313 + £8 for the Rada route
08 · Safety & limits

What we are not going to touch

  • The thermostatic limit stays the valve's. Every route asks the valve for a temperature; the valve's own maximum (41 °C as shipped, TMV3) and its thermistor shutdown still apply. Nothing here can make water hotter than the panel can. The ESP configs clamp at 41 °C as a second fence.
  • No mains work. Everything lives on the 12 V / 9 V side. The PSU stays sealed and on its fused spur.
  • The panel keeps working. Route 2 relays it; Routes 1 and 3 never interrupt it. If the ESP dies, the shower is exactly as it was.
  • Voice cannot leave it running. The auto-off timer is in Home Assistant and the valve's own run time is a third layer; set that to 20 minutes in the app rather than 60.
  • Disinfection stays manual. The Modbus map has an arm/trigger sequence for 60–80 °C thermal disinfection. We never send it and the HA package has no path to it.
  • Warranty and WRAS. Splicing the panel cable is reversible with two connectors and does not change the water side; the valve remains a WRAS-approved TMV3. If Rada ever service it, unplug our board and the cable is as delivered.
Send me, in any order

The nRF Connect screenshot, the valve label photo, the connector photo with your pin voltages, and the core count. With those I write the exact firmware for the route that opened, the same day.