Table of Contents
- Fossil / Skagen Hybrid HR
- Screenshots
- About the device
- Connecting to Gadgetbridge
- Obtaining the necessary secret key
- Method 1: Using FossilHRAuthenticator
- Method 2: Use a python script to fetch the key
- Method 3: Using a patched official app
- Method 4: Get secret key from app cache (Skagen only)
- Method 5: Using mitmproxy (sniffing decrypted https traffic)
- Pairing and connecting to Gadgetbridge
- Factory reset
- Device name
- Widgets on the watchface
- Usage
This page has moved
⚠ The wiki has been replaced by the new website - this page has been moved: https://gadgetbridge.org/gadgets/wearables/fossil/
Fossil / Skagen Hybrid HR
The support for the Fossil Hybrid HR in Gadgetbridge is considered stable and mature.
Contents
Screenshots
Screenshots and photos to give an impression of the actual usage. Click on the images for larger versions.
The main screen, the watchface designer, the app manager, and the custom menu editor
Watchface with regular widgets, watchface with custom widgets, custom menu, and snake game
About the device
The Fossil Hybrid HR is an ePaper Hybrid smartwatch with real hands on a round epaper display with over two weeks of battery. The same device is also sold with slightly different cases under the Skagen brand. Both the original generation and the Gen 6 devices are supported. Please refer to the feature support matrix below for differences between the official app and Gadgetbridge.
Feature support matrix
Feature | Gadgetbridge | Official app | Notes |
---|---|---|---|
Time synchronization | Yes | Yes | |
Hands calibration | Yes | Yes | |
Steps | Yes | Yes | |
Heart rate | Yes | Yes | |
Sleep tracking | No | Yes | Not tracked by watch but calculated by algorithm in official app |
GPS workouts | Yes | Yes | Needs OpenTracks 3.29.0 or later installed |
Phone notifications | Yes | Yes | Settings under Notification settings in Gadgetbride menu, not in device settings |
Call accept/decline | Yes | Yes | |
Dismiss call with SMS | Yes | Yes | |
Weather info | Yes | Yes | See https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Weather |
Physical buttons | Yes | Yes | |
Music info and control | Yes | Yes | |
Alarms | Yes | Yes | Last alarm slot is used for quick alarm set from the Widget |
SpO2 measurements | WIP | Yes | Partially implemented, not released yet |
Alexa commands | No | Yes | Initial support started, no progress lately |
Watchface configuration | Yes | Yes | Watchfaces on firmware DN1.0.2.20r and up are only supported by Gadgetbridge 0.59.0 and up |
Google Fit integration | No | Yes | Gadgetbridge has no internet permissions |
Privacy friendly | Yes | No | |
Tasker/Intent actions | Yes | No | See below for configuration examples |
Custom apps | Yes | No | |
Custom menu | Yes | No | Requires extra companion app |
Custom widgets | Yes | No | Requires Tasker or other Intent sending app |
Known watch apps
App name | Official | Description | |
---|---|---|---|
launcherApp | Yes | New on-watch menu introduced with official app v5 | |
settingApp | Yes | Settings menu | |
notificationsPanelApp | Yes | Notifications list and actions | |
musicApp | Yes | Music control | |
ringPhoneApp | Yes | Locate phone from watch by ringing it | |
stopwatchApp | Yes | Stopwatch | |
timerApp | Yes | Countdown timer | |
weatherApp | Yes | Shows weather info | |
wellnessApp | Yes | Health dashboard | |
AlexaApp | Yes | Gen6 only: records audio command and shows response from Alexa | |
commuteApp | Yes | Displays commute times, but can be used to interface with Easer/Tasker. Discontinued in official companion app v5. | |
workoutApp | Yes | Records workouts. Built into firmware. | |
themeApp | Yes | Hidden on-watch watchface switcher. Built into firmware. | |
navigationApp | No | Displays navigation instructions from OsmAnd and Google Maps. Distributed with Gadgetbridge. | |
snakeApp | No | Snake game | |
timerApp | No | Integrated timer/stopwatch/alarm app | |
weatherApp | No | Dutch weather app integrating Buienradar graph and KNMI forecast |
The app names in the table above can be used in the custom menu companion app. See below for details.
Supported watches
All e-ink hybrid watches currently known from Fossil, Skagen and Citizen are supported. Note: the Gen 6 OLED smartwatches are not supported.
Watch series | Hardware revision |
---|---|
Fossil Hybrid HR 42mm (Collider and others) | DN1.0 |
Fossil Hybrid HR 38mm (Monroe and others) | IV0.0 |
Fossil Gen 6 Hybrid 44mm/45mm (also Wellness) | VA0.0 |
Skagen Jorn 42mm Gen 6 | VA0.0 |
Skagen Jorn 38mm Gen 6 | WA0.0 |
Known firmware versions
Version | From Fossil app | md5sum | Comments |
---|---|---|---|
DN1.0.2.3r.prod.v8 | unknown | Pre-installed, probably no real functionality except firmware update | |
DN1.0.2.12r.v2 | be93342d27f6b837688a05098d240051 | ||
DN1.0.2.14r.v4 | 2af029ab917ed7825287f69abd2b4904 | ||
DN1.0.2.16r.v9 | 06a7f6d32c36ddea28019805e76c6c32 | ok | |
DN1.0.2.17r.v5 | 4.3.0 | 387a2645c5f4117e294afeeb2c17b797 | ok |
DN1.0.2.18r.v9 | 4.4.0 | 9695d8562b4d6b8ee0f4461dc5633370 | ok |
DN1.0.2.19r.v5 | ok | ||
DN1.0.2.19r.v7 | 4.5.0 | b0194f9ad9346319d20ee29b67c22dd6 | ok |
DN1.0.2.20r.v5 | 4.6.0 | ok | |
DN1.0.2.21r.v1 | 4.6.0 | ec75a07a151ef6b57a8fe4ad607371eb | upgrading to this version will invalidate your auth key, see notes |
DN1.0.2.22r.v4 | 4.7.0 | b9b9bafcbcde0b6c08f8cdb6c086de9c | ok |
DN1.0.2.22r.v5 | 4.8.0 | 0cb3bc6391b3c9a546afecbc53e70f07 | ok |
DN1.0.2.23r.v2 | 4.9.0 | 981c168fb879047accdc22a5b695393c | ok |
DN1.0.3.0r.v3 | 5.0.0 | 6f650adf6da0ffde0d432a8edcc721bc | ok |
DN1.0.3.0r.v8 | 5.0.1 | c9a2cca8f2bd2b09869c648ef8b4de15 | ok |
DN1.0.3.0r.v9 | 5.0.3 | 3dac8e6cdc2abad18883d23c4fa58fdb | ok |
DN1.0.3.0r.v13 | 5.1.2 | ok |
Notes:
- From DN1.0.2.18 up, more and more watch functions have moved from the firmware to watch apps. They can be uploaded with Gadgetbridge but we cannot re-distribute them. To make sure the watch is in fully working condition, upgrade it using the latest official Fossil app before switching to Gadgetbridge.
- It's possible to switch back and forth between the original app and Gadgetbridge if required for some reason. However the watches' secret key may change if you re-pair it with the official app, so you may need to repeat the key extraction process described below after switching back and forth.
Connecting to Gadgetbridge
Obtaining the necessary secret key
Unfortunately the device is pretty locked down and it is necessary to use the official app at least once. This is has two reasons:
- The device seems to come with a demo firmware that is not functional and needs to be updated once. This can only be done in an official app. 2) There is a secret per-device key that gets negotiated with the Fossil servers. This process seems to be cryptographically secure, unfortunately.
You have to (later) make sure that the official app and Gadgetbridge do not collide with each other, perhaps have the official app installed on some other device and keep the device/bluetooth off...
We currently know of several methods to authenticate the watch and retrieve the auth key. They are outlined here, in increasing complexity:
Method 1: Using FossilHRAuthenticator
- Fetch the secret key from official servers. This allows the same key to be used in Gadgetbridge and in the official app. 2) Create a shared secret for Fossil HR watches and more - this app allows authenticating against all endpoints that support the same protocol. Use the values displayed in the README for retrieving the key from the Fossil servers.
https://github.com/dakhnod/WatchAuthenticator
Method 2: Use a python script to fetch the key
Click to see the code of the python script
#!/usr/bin/env python3
import requests
import sys
import json
import base64
def die(s, r):
print(s, file=sys.stderr)
print(r.text, file=sys.stderr)
sys.exit(1)
if len(sys.argv) != 3:
print("Usage: %s username password" % (sys.argv[0]), file=sys.stderr)
exit(1)
email = sys.argv[1]
password = sys.argv[2]
base_url = 'https://c.fossil.com/v2.1' # use for fossil watches
#base_url = 'https://api.skagen.linkplatforms.com/v2.1' # use for skagen watches
auth_url = base_url + '/rpc/auth/login'
keys_url = base_url + '/users/me/device-secret-keys'
# add in the email and password
auth_fields = {
"email": email,
"password": password,
"clientId": "xxx",
}
# try to fetch the auth URL with this username / password
r = requests.post(auth_url, json=auth_fields)
if r.status_code != 200:
die("wrong username/password?", r)
token = json.loads(r.text).get("accessToken")
if not token:
die("no access token in results?", r)
# now we can fetch the device keys using the bearer token
r = requests.get(keys_url, headers={
"Authorization": "Bearer " + token,
})
if r.status_code != 200:
die("access token not valid?", r)
devices = json.loads(r.text).get("_items")
if not devices:
die("no devices in response?", r)
for dev in devices:
devid = dev.get("id")
key = dev.get("secretKey")
if not key:
die(devid + ": no secret key?", r)
# only output the first 16 bytes of the secret key
print(devid, base64.b64decode(key).hex()[0:32])
Method 3: Using a patched official app
There is a patched official app which will reveal the key. This will downgrade the watch firmware though, so after retrieving the auth key with the patched app, you will need to install the latest official app from the Play Store to upgrade the watch to the latest firmware. This will not change the auth key.
WARNING: the Gen 6 hybrids didn't exist yet when this app was released, so this method won't work for those.
Method 4: Get secret key from app cache (Skagen only)
NOTE: This method needs independent verification, at the time of writing only the author did it
You need a rooted phone for this to work
- Start with a clean slate, i.e. the official app must not be paired with your watch yet.
- Pair the watch as usual.
- Search for
secret
in the apps internal cache directory, e.g. for the Skagen app that is/data/data/com.skagen.connected/cache
. There are many ways to do that, I used adb and the commandgrep -rIi secret .
, you can do the same with termux or just copy that directory to your compute and search the directory with your favourite tools. I found the following (truncating some potential PI):
./cacheResponse/c4280c8aa94ab69d6fa8a9521d3dccc5.0:https://api.skagen.linkplatforms.com/v2/users/me/devices/D0S00212GU/secret-key
./cacheResponse/c4280c8aa94ab69d6fa8a9521d3dccc5.1:{"id":"...","uid":"...","secretKey":"DIcI3xns...d4K4mOh0=","createdAt":"2022-05-24T18:53:29.624Z","updatedAt":"2022-05-24T20:06:09.736Z","_links":{"self":"/v2/users/me/devices/.../..."},"_etag":"...","_isNew":false}
What we are interested in is the secretKey
value.
- Convert the key to be used in Gadgebridge, see instructions below for mitmproxy (command includes
hexdump
).
Method 5: Using mitmproxy (sniffing decrypted https traffic)
NOTE: this section is probably outdated and needs testing
Requirements
To do it this way, you need the following
- A rooted Android device (if you can use a junk tablet which is not your phone)
- A PC running Linux on the same network
- mitmproxy and knowledge of using of how to use it.
The procedure is generally speaking (there should be detailed tutorials on using mitmproxy elsewhere)
- Run mitmproxy
- Convert the auto-generated certificate to your rooted android phone in the appropriate folder
- Setup iptables to forward traffic though mitmproxy
- Test if mitmproxy works (you should see decryted output when you use the browser and go so some https site)
Running the Fossil App with mitmproxy enabled
- Now when you register a new device you can inspect the traffic from/to Fossil servers in mitmproxy. Facebook is also fed with data. You cannot opt out, but you can block the traffic.
- Look for a PATCH request to the Fossil server ending with /secret-key (even if it has a 404 response)
- press enter on that request and loop at the JSON. There your will see a 256 byte key that is base64 encoded, it will look something like this:
"secretKey": "eriwogvjmerighDFGWERj45jdfgsd345FDGdfgdfgdf="
- Do the following (insert your key)
echo "eriwogvjmerighDFGWERj45jdfgsd345FDGdfgdfgdf=" | base64 -d | hexdump -C
- Take the first 16 bytes of the output, in our example this is
7a b8 b0 a2 0b e3 99 ea e2 82 10 c5 19 61 11 8f
, remove the spaces and prefix with 0x, igrore the second 16 bytes (second line), we don't need it. - This is your key you need for Gadgetbridge (here: 0x7ab8b0a20be399eae28210c51961118f)
NOTE: You need to fininsh the firmware installation to the Watch, and then activate your watch, if the process is interrupted, you need to start over, and you will get a new key, the old one will be invalid, so make sure to keep mitmproxy running until the watch is usable.
Pairing and connecting to Gadgetbridge
- Uninstall the fossil app if you plan to use Gadgetbridge on the same device you obtained the key on, unpair the Watch from Android settings if it is paired
- Open the main Gadgetbridge settings in the drawer on the left of the app, then
open the "Discovery and pairing options" near the bottom and configure the following
settings:
- Increase the scanning intensity in case your watch isn't found at all
- Disable "Discover unsupported devices", because otherwise the watch will be discovered as UNSUPPORTED
- Enable "CompanionDevice pairing", to allow for example "Find my phone" to work correctly in Android 10 and up.
- Press the + button (Connect new device in the menu) in Gadgetbridge
- Wait for the Fossil watch to be discovered
- After the watch is found, long tap on the "Fossil" Watch in the device list and enter (paste) the secret key into the Auth key. Make sure you have no line breaks or spaces in your input and that it starts with 0x. Then go back to the list of devices.
- Tap on the Fossil watch in the list, the watch should start connecting now
- You will be asked (by Android) to Pair with Fossil. You should pair, otherwise the watch will keep asking to confirm device connection. Companion device pairing may ask for confirmation - confirm it.
- Watch should connect
Factory reset
If you have hard time pairing the watch and you need to factory reset it, here is how. Source and more details on reddit.
- Remove My Watch in the watch settings in the fossil app
- Go to Bluetooth settings and forget the Fossil Watch
- Press and hold the middle button until the watch buzzes hard and it resets
- Set the watch on its charger
- Press and hold the center button AGAIN until the watch resets again
- Open the fossil app and “Pair my First Watch”
Device name
Depending on your model, the device should show a correct name (Q Commuter, Q Activist, Hybrid HR Collider).
Widgets on the watchface
In order to have widgets (complications) like date, steps, weather... on the watchface, you must enable it in the watch settings: long press middle button → Settings - Dial info → ON
Usage
Using Tasker, Easer or another automation app
Note: information taken from here, here and here.
Several of the usage descriptions below require the use of Tasker, Easer or another app that can send custom broadcast Intents.
Commute app
- Configure one or more Actions in Gadgetbridge. These will be your Commute destinations. Example: "Test"
- Create a profile in Tasker with the event "Intent Received" with the following content:
- Action:
nodomain.freeyourgadget.gadgetbridge.Q_COMMUTE_MENU
- Action:
- Create a task in Tasker with the following content:
- If:
%extra_action
EQTest
- Send Intent
- Action:
nodomain.freeyourgadget.gadgetbridge.Q_SET_MENU_MESSAGE
- Extra:
EXTRA_MESSAGE:Test action received!
- Extra:
EXTRA_FINISHED:true
- Action:
- If:
You may set EXTRA_FINISHED
to false if the watch is to wait for more content
from the phone, and then send another intent with more content.
Custom widgets (firmware DN1.0.2.20r and newer)
- Configure one or more custom widgets in Gadgetbridge 0.63.0 or higher
- Note down the widget numbers as shown on the watch
- Create a task with name
Send custom widget 0 config
in Tasker and add the action Send Intent with the following content:- Action:
nodomain.freeyourgadget.gadgetbridge.Q_PUSH_CONFIG
- Extra:
EXTRA_CONFIG_JSON:{"push":{"set":{"widgetCustom0._.config.upper_text":"%par1","widgetCustom0._.config.lower_text":"%par2"}}}
- Action:
- Create more tasks like the above for every custom widget number. This greatly reduces complexity in using it later on
- To send data to the custom widgets, create another task which will retrieve/generate the text and add the action
Perform Task
with for example the following content:- Name:
Send custom widget 0 config
- Parameter 1:
Home
- Parameter 2:
21°C
- Name:
Custom widgets (firmware DN1.0.2.19r and older)
- Configure a custom widget in Gadgetbridge
- Create a task in Tasker and add the action
Send Intent
with the following content:- Action:
nodomain.freeyourgadget.gadgetbridge.Q_SET_WIDGET_CONTENT
- Extra:
EXTRA_WIDGET_ID_temp:21°C
- Action:
Custom menu
Gadgetbridge 0.67.0 introduced a new custom menu functionality for the Fossil/Skagen HR watches. The setup and usage of this custom menu is considered applicable for advanced users only, so no direct support was built into Gadgetbridge. Instead, a separate Fossil HR Menu Companion App was introduced to configure the custom menu.
Because the custom menu is integrated in the Fossil HR Gadgetbridge watchface code, it is necessary to re-upload the watchface to the watch using Gadgetbridge 0.67.0 or newer. Watchfaces uploaded with older Gadgetbridge versions do not contain the custom menu functionality yet.
When a custom menu action is configured to send data to the phone, it will do so using a commute app event. Refer to Commute app for details on how to handle these events.
Custom text can be shown on the left side of custom menu screens. To do so, send a broadcast Intent using one of the apps mentioned before, in this format:
- Action:
nodomain.freeyourgadget.gadgetbridge.Q_PUSH_CONFIG
- Extra:
EXTRA_CONFIG_JSON:{"push":{"set":{"customWatchFace._.config.response":{"message":"text here","is_finished":true}}}}
NOTE: the physical menu buttons configured in Gadgetbridge will override the watchface-level buttons configuration from the Menu Companion app.
Custom menu embedding
As stated above, the HR Menu Companion
is used to send the custom menu structure to the watch.
The menu structure will be lost on the watch after the watch crashes or reboots.
As of recently, GB will remember that structure and embed it in the watchfaces that are installed henceforth for persistance.
So, to make the menu configuration on the watch permanent follow these steps:
- Build the menu using the
HR Menu companion
- Send the menu structure to the watch from the companion
- Test the menu on the watch
- Delete the watchface in GB
- Rebuild your watchface from scrath in GB and install it on the watch. The new watchface version should be above 1.10
- Done. The menu configuration is now baked into the watchface
Custom apps
The Hybrid HR supports installing apps from non-official sources, even though the official Fossil app doesn't allow this. Gadgetbridge includes an App Manager that can upload apps to the watch and delete apps on the watch. Internally, uploaded watchfaces are apps as well, so they can be managed through the App Manager too.
Developers can use the Fossil HR SDK and its examples to develop new apps.
One example of a ready made app is Better Timer. It replaces the default Stopwatch App and includes timer, stopwatch and alarm functionality combined in one app. To install, simply download the .wapp file on your phone, then upload it using the Gadgetbridge App Manager.
Automatic watchface switching
With the latest firmware (DN1.0.3.0*), the watch can contain 2 watchfaces. It is possible to switch between these watchfaces via the app manager by tapping on them. Starting with Gadgetbridge 0.68.0 it is also possible to automate this step by sending an Intent from an app like Tasker.
Use the following contents in a broadcast Intent to switch watchface:
- Action:
nodomain.freeyourgadget.gadgetbridge.Q_SWITCH_WATCHFACE
- Extra:
WATCHFACE_NAME:NewWatchface
Activity tracking with OpenTracks integration
The official Workout app is supported by the OpenTracks integration. Just start a run or cycling workout and Gadgetbridge will automatically use OpenTracks for recording the track and providing statistics to the watch, exactly like the official app does without OpenTracks.
Do Not Disturb functionality
In the Hybrid HR settings on the watch, there is an option to mirror the Do Not Disturb mode on the phone. For this feature to work as expected, notifications will have to be sent to the watch regardless of the active Do Not Disturb mode on the phone. To achieve this, Gadgetbridge's global Do Not Disturb option in Notification Settings must be disabled. If this setting is enabled, all notifications that are suppressed by the phone's Do Not Disturb setting will be ignored completely.
NEW WEBSITE
General
- Home
- FAQ
- ReadMe
- Configuration
- Notifications
- ChangeLog
- Widget
- Weather
- Data Backup
- Pairing
- Find phone
- Music info
- Permissions Explained
- Firmware Update
- Automation via Intents
Sports/Activities
- Sports Activities Workouts
- Activity Sessions List
- Activity and Sleep Charts
- Heartrate measurement
- Integrating Sports Tracking apps with Gadgetbridge Sports Activities/Workouts
Smart Device Related
- Bangle.js
- Casio devices
- FitPro
- Fossil Hybrid HR
- Garmin devices
- HPlus
- Huami devices
- Amazfit Active
- Amazfit Active Edge
- Amazfit Balance
- Amazfit Band 5
- Amazfit Band 7
- Amazfit Bip
- Amazfit Bip Lite
- Amazfit Bip S
- Amazfit Bip U
- Amazfit Bip 3 Pro
- Amazfit Bip 5
- Amazfit Cheetah
- Amazfit Cheetah Pro
- Amazfit Cor
- Amazfit Cor 2
- Amazfit Falcon
- Amazfit GTR
- Amazfit GTR 3
- Amazfit GTR 3 Pro
- Amazfit GTR 4
- Amazfit GTR Mini
- Amazfit GTS
- Amazfit GTS 3
- Amazfit GTS 4
- Amazfit GTS 4 Mini
- Amazfit Neo
- Amazfit T-Rex
- Amazfit T-Rex 2
- Amazfit T-Rex Ultra
- Mi Band 1
- Mi Band 2
- Mi Band 3
- Mi Band 4
- Mi Band 5
- Mi Band 6
- Mi Band 7
- MyKronoz ZeTime
- Pebble
- PineTime
- Sony Wena 3
- SMA
- WithingsSteel
Wireless Earbuds
Others
- iTag Keyring trackers
- Nut Keyring trackers
- UM25 USB Voltage meter
- VESC BLDC controller VESC
- Flipper Zero Multi-tool Device for Geeks
- Roidmi Roidmi/Mojietu FM Trans.
- Vibratissimo Private toy
- Shell Racing Toy RC cars
- Femometer Vinca II
Full list of supported devices
Development
- How to Release
- Developer Documentation
- BT Protocol Reverse Engineering
- Support for a new Device
- New Device Tutorial
- Translating Gadgetbridge
- OpenTracks-API
- Intent-API
Feature Discussion
FAQ