You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am the developer behind <a href="https://sleepbreeze.eu/">SleepBreeze</a>, a sunrise alarm lamp designed to simulate natural daylight and support a gentle wake-up experience. The lamp gradually increases brightness and color temperature in the minutes leading up to the alarm.
16
16
</p>
17
17
<p>
18
-
I designed and implemented a production-ready, cross-platform mobile application in React Native (Expo) that controls the device over Bluetooth Low Energy (BLE). The app supports both iOS and Android and is currently available on the Polish market.
18
+
I designed and implemented a production-ready, cross-platform mobile application in React Native (Expo) that controls the device over Bluetooth Low Energy (BLE). The app supports both iOS and Android and has been shipped to first users on the Polish market.
19
19
</p>
20
20
</div>
21
-
<div class="col-6 col-md-4">
21
+
<div class="col-12 col-md-4">
22
22
{% include video.liquid path="assets/img/sleep_breeze/sunrise_video_cropped.mp4"
23
23
class="img-fluid rounded z-depth-1"
24
24
controls=true autoplay=true %}
@@ -28,7 +28,7 @@ related_blog_posts: false
28
28
</div>
29
29
</div>
30
30
31
-
##Key features
31
+
# Key features
32
32
33
33
- Bluetooth LE device discovery, pairing, and reconnection
34
34
- Full light control: power, brightness, color temperature, and RGB (where supported)
@@ -53,14 +53,43 @@ related_blog_posts: false
53
53
Selected screens from the Android and iOS applications.
54
54
</div>
55
55
56
-
## Technical highlights
57
-
58
-
- Reverse-engineered the BLE communication protocol of the smart bulb, including service/characteristic discovery and low-level byte-level command encoding
59
-
- Built custom native modules for Android and iOS to ensure reliable alarm execution despite OS-level battery optimizations and background execution limits
60
-
- Designed a robust app architecture supporting unreliable BLE connections and device state recovery
61
-
62
-
## Links
56
+
# Links
63
57
64
58
- 🌐 [Official website](https://sleepbreeze.eu/)
65
59
- 📱 [App store listing](https://apps.apple.com/pl/app/sleep-breeze/id6744585835)
Working with undocumented BLE devices like Philips HUE, with no official documentation of communication protocols is never a pleasure. To understand inner workings of peripheral devices, I had to reverse-engineer the BLE protocols by sniffing Bluetooth packets and analysing them in [Wireshark](https://www.wireshark.org/).
76
+
77
+
This experience thought me a lot about the BLE protocol itself, reverse engineering and low-level communication with IoT devices in general.
78
+
79
+
### Implementing robust alarm functionality
80
+
81
+
One of the clients requirements was to have a reliable sound alarm functionality that would trigger along the sunrise alarm. I didn't expect this to be such big of a challenge, but quickly realised that mobile OS-es are quite restrictive when it comes to background task execution. Especially developing a React Native app adds another layer of complexity and abstractions from the native APIs.
82
+
83
+
As the platforms don't expose native APIs to schedule built in alarms from 3rd party apps, I had to find some working solutions.
84
+
One of the initial approaches was to use repeated notifications (either local or push) with sound to wake up user on time. However, one of the clients requirements was to have the alarm sound gradually increase in volume for a longer period of time (e.g., 3 minutes) for a gentle wake-up experience. Unfortunately notification don't support either long sound playback or volume control, and could be easly muted by the user.
85
+
86
+
Therefore, I resorted to media playback in the background as the music apps do. This would allow playing arbitrary sound files and provide volume control. However problem remains of having reliable background trigger to play the sound at the right time.
87
+
88
+
On iOS, I noticed that the JS runtime doesn't get suspended if there is an active audio playback session.
89
+
This key observation allowed me to implement a workaround: When user sets the alarm, the app immediately starts playing a "sleep music" audio file at very low volume in the background. This keeps the JS runtime active and allows to use plain `setTimeout` to schedule the proper alarm playback at the right time.
90
+
91
+
On Android however this approach didn't work as JS runtime gets suspended more aggressively and the OS battery optimization [depends on the manufacturer](https://dontkillmyapp.com/).
92
+
Fortunately there is Android specific API of foreground services, which allows to run long-running background tasks. This is used by the apps like Uber to give you notifications about your ride even when the app is not in the foreground.
93
+
Therefore I used that to implement a foreground service that gets started when user sets the alarm. Then I set a callback task to be executed at the alarm time, which starts the gradual sound playback and notifies the user.
94
+
95
+
To summarize, implementing reliable alarm functionality was more challenging that I expected, but I am happy with the final result.
0 commit comments