Vapaamin - Garmin notifications bridge

So, looking at @ropeta comments and having same issue with not having native notifications on my Garmin watch, I’ve spent almost entire weekend trying to port what I found on Gadgetbridge and also Amazfish.

Here’s the code: https://codefloe.com/sznowicki-sailfish/vapaamin

What works:

  • it builds, runs
  • it installs a daemon that listens to SFOS notifications
  • app does the GFDI handshake with the watch so it thinks it talks to a real Garmin Connect app
  • when notification reaches the app, it forwards it to the watch

It was surprisingly lot of work, most of it I understand only to some degree. So if @piggz solution will work for me I guess I’m more than happy to take what I’ve learned these days with me and archive this one.

However, the Amazfish support message reached to me exactly as I opened Forum to post about how happy I am that this worked out in the end and I have my notifications now on my wrist…

One comment about the API. It should not be necessary to run some crazy privilidged daemons and disable sandboxing of the entire app, just to be able to read global notifications. This should be a permission, and a nice API provided by SFOS itself, with a big-ass warning to the users on what kind of permission they grant to that app and what are the consequences.

LLM learnings:

While working on it I approached it like usual, with Opencode and Kimi/GLM models and unfortunately it ended up in a mess of guess work. At one point I decided to pay for Claude again to see if I would be able to wrap my head around Garmin watch auth parts. Claude did amazing job in explaining me how this works on Gadgetbridge so I guess I could do right choices and steer it into doing what you can check as a result.

We have that joke in Polish:

A coal salesman approaches a delivery address and shouts: I’ve bring your coal!

Horse looks at him thinking: yeah, you bring it…

So, I’ve made myself an app. I’m not sure if I’m proud of it tbh but I’m sure it sends me my notifications to my wrist.

7 Likes

How did you find QML part after playing with it for a weekend?

I bet you’ve learned a thing or two. Kudos to you for being open about using LLMs!

QML part is the easy one since I`m a web developer and also have some experience with SwiftUI. This is where I feel most comfortable with. C++ is where I feel weak.

I think QML is amazing. Strong plus.

This is how amazfish started …. i wanted to learn a bit about BLE and get notifications on my Bip … and now its grown!

3 Likes

What issues? I dont have issues on my Jolla Phone 2. I have notifications working and calendar from Outlook (Android)

If you use Garmin Connect you only have notifications from Android apps. So for people who prefer going as native as possible, this restricts push reaching your wrist to just a subset of them, most of them I’m not even interested seeing. I want to see email and matrix notifications, all of them I use as native apps.

I dont know if its even possible to code since isint it the code closed on Garmin? You would have to code app for Sailfish to run in the sailfish and coding it to work on the watch/ device, then the app would need to understand and give notifications from the Sailfish

That’s exactly what I did last weekend and what this code is doing (except it’s not running on a device, but on SFOS phone).

The worklow/architecture is as follows:

The daemon binary is installed and listens to all SFOS notifications, when one is there it offers it to the main UI app.

Main UI app maintains bluetooth connection via proprietary, previously reverse-engineered by Gadgetbridge, protocol.

Using that protocol, it sends those previously sniffed notifications to the watch.

Watch thinks the connection is from Garmin Connect app.

2 Likes

Here’s a screenshot of how it looks like when it’s fully working, red stuff is censored parts.