A Bluetooth app where every tap gets an answer
An app for iOS and Android that controls lighting controllers over Bluetooth Low Energy, built for a client, for end users who are not technical.
Every tap gets an answer.
- sent
- superseded
- failed
- busy
- current
- not-connected
The problem
The users are not technical: they only know "the lights" and often control them in the evening, from their phone. The client wanted one app of its own for three kinds of lighting products, one that feels like part of a premium installation and not like a generic LED app.
What I built
An app that recognises the different controllers by itself, reconnects as soon as they can be reached again, and shows honestly on every tap whether the command arrived.
Translated into nine languages, Arabic right to left among them.
What matters technically
One supervisor that reconnects by itself
Every product family gets the same supervisor, which reconnects on a fixed back-off schedule. Cancelling invalidates every attempt in flight, so a connection that arrives too late is ignored instead of causing a race.
Latest value wins
While a colour or brightness slider is dragged, only the latest value per setting goes out. The connection never fills up, and the user's last choice always arrives.
Every tap gets an outcome
A tap is sent, overtaken by a newer choice, or refused with a reason: busy, already set or not connected. Every write times out after two seconds, so nothing hangs silently.
Up to ten controllers at once
A separate manager keeps several connections at once and puts the writes in line. There is one desired state, so a controller that falls behind catches up in a single write.
Architecture rules fixed in tests
One test makes sure the design system never imports from the Bluetooth layer, another that every language has exactly the same translation keys.
Nine languages, right to left too
Arabic lives in the base components themselves, such as arrows and swipe-back that turn with the reading direction.
Measured
Counted in the repository, not estimated.
- test files
- 130
- test cases
- 1,755
- lines of test code, against 27,114 lines of app
- 33,977
- languages, Arabic among them
- 9
- controllers at once, at most
- 10
How measured
git ls-files 'src/__tests__/*.test.ts*' | wc -l
git ls-files 'src/__tests__/*.test.ts*' | xargs grep -cE '^\s*(it|test)\(' (summed)
git ls-files 'src/__tests__/*' | xargs wc -l
git ls-files 'src/*.ts' 'src/*.tsx' 'app/*.ts' 'app/*.tsx' plugins | grep -v __tests__ | xargs wc -l
ls src/i18n/locales | wc -l
the limit in the connection managerMeasured on 27-10-2026 in the app's repository.
Need something similar, or a team that builds systems like this?
info@bitvire.com