A touch-screen remote control for Linn Selekt DSM, using Rust on ESP32
While engineering the requirements for a client project to build a lighting control app to run on the infotainment / Cabin Management System (CMS) iPads on a Bombardier Global 6000 jet (like this), I came across this integrated screen/rotary dials built into the newest version of these planes.
While such custom hardware and embedded development was not something feasible on the given timeline (and would require physical changes to the aircraft), creating such a purpose-built gadget left me intrigued. Since I have no API-enabled smart lighting system at home, I instead opted to build a remote for my Linn Selekt DSM HiFi system instead. I knew that it does have an API, and having a dedicated piece of hardware seemed so much nicer than having to use the iPhone app (which does not have any live activities or similar to speed up control).
We all have desires, things we want to build, ways to express ourselves, ways that we find joy and meaning.
– Scott Wu
As it turns out you can even get a basic variant of that hardware (IPS instead of OLED, but a solid “scroll wheel” with a ball-bearing around the display) on Amazon1. Unfortunately that device’s chip (ESP32-S3) is a little harder to get started with using my preferred Rust toolchain, so I opted for a ESP32-C6 board with an OLED display (but sadly no wheel) instead.
Luckily the overall development environment is stable at this point and the basic setup to get started is well documented. With those docs and Claude I was able to get a basic “app” running on that device in no time at all.
The streamer has a documented control protocol and with a bit of debugging real responses a client class was built in no time. On the UI layer the generated code was a bit convoluted in the “AI does not tire of writing code”-sense, e.g. display and touch handling were entirely distinct, even though of course there should be a close relation between what’s rendered on screen and what areas receives touches. But with my previous knowledge of the Flutter rendering stack, I guided the implementation in a direction I felt comfortable with, building small widgets which only redraw their own area of the screen, and having input aligned with the rendering.
One downside of the hardware I picked is that it doesn’t have a built-in battery, which would be really cool for a remote. So for now I have to tack one to the back, but I hope that the next generation of ESP32-S31 boards will come in a nicer packaging so that I can revisit this again.
Having the physical rotating knob would be an especially nice upgrade, and overall the displays could always be a bit bigger and higher resolution.
But after a bit of tinkering the whole package works now: It connects to WiFi and can be powered off via the hardware button and thus lasts a long time without needing a charge.
![]() | ![]() |
So overall I am happy about how this turned out and how it made me change my mind on what’s possible to build. Looking forward to what’s next!
How many ideas does one person have in a day, and how many of those things do they actually get to do? Until that proportion is 100%, you know there is a pretty meaningful bottleneck in terms of the drudgery of execution.
– Scott Wu
The full code is available on GitHub.
Footnotes
-
For that specific board there is even a fully implemented Roon remote control up on GitHub. ↩



