openHAB for Garmin connects your Garmin wearable to your openHAB smart home system, giving you convenient access to essential devices and real-time information.
Resources
➡️ Install on Garmin Connect IQ Store
➡️ openHAB Community Discussion
Development Status
🚧 This app is in an early stage of development. Core features are available, and active development is ongoing.
This app is built on the foundation of openHAB sitemaps, which define an interactive view of your openHAB model. A sitemap allows you to specify which devices are accessible through the app and how they are organized and presented.
The app consists of two components: the Glance and the Widget. The Glance displays the name of the sitemap and acts as the entry point into the full-screen Widget, which shows the sitemap’s content.
![]() |
![]() |
Once opened, the Widget polls the sitemap at a configurable interval to fetch updates. Commands are sent to openHAB via its JSON-based REST API. If your openHAB setup does not support this API, you can alternatively configure a custom Webhook.
Inside the Widget, sitemap elements are displayed as Sitemap Widgets. Note: The term “widget” is used by both Garmin and openHAB to mean different things, which can be a source of confusion. In this manual, “Widget” refers to the Garmin app component, while “Sitemap Widget” refers to individual elements defined in the openHAB sitemap.
The following sections provide detailed guidance on configuring the app, supported Sitemap Widgets, user interface behavior, and troubleshooting tips.
Once the app is installed, you can configure the following settings by opening it in the Garmin Connect IQ smartphone app.
Setting | Description |
---|---|
URL | Your openHAB URL in the format https://host:port or http://host:port . Note: HTTP only works with iOS. See Connectivity and Using myopenHAB for details. |
Sitemap Name | Name of the sitemap to display. See Sitemap Setup for details. |
Native REST API Support | Enable if your openHAB supports the new JSON-based REST API for sending commands. See Sending Commands for details. |
Webhook Identifier | If your openHAB version doesn’t support the JSON-based REST API (see above), you can configure a custom webhook to send commands. See Custom Webhook for details. |
Username | For basic authentication (used for myopenHAB, see below) |
Password | Password for basic authentication |
Supress empty response errors | Suppress errors for empty sitemap responses. Recommended when using myopenhab.org, which occasionally returns empty results. See the related openhab-cloud issue #496 for details. |
Polling Interval (ms) | Interval between data requests to your openHAB instance. Set to 0 to fetch new data immediately after the previous response is processed. Polling only occurs while the app is open, not in the background. If you’re using myopenhab.org, it’s recommended to use the default (3000 ms) or a higher value to avoid overloading their servers. If you’re connecting to your own openHAB server directly, you may try setting it to 0 for more responsive updates. |
Garmin wearables rely on your smartphone for network access. If your phone can reach your openHAB instance (e.g. via local network or VPN like Tailscale), the watch can too.
Platform-specific Limitations
You can use myopenHAB to securely access your local openHAB instance over the Internet using HTTPS.
To connect using myopenHAB:
https://home.myopenhab.org
Starting with openHAB 5, a built-in JSON-based REST API enables this app to send commands directly—no additional setup required.
For earlier versions (openHAB 4.x), you can either install a backported version of the API or configure a custom webhook.
To enable JSON-based command support on openHAB 4.x, install the backported API bundle. Follow the instructions here:
➡️ Backport Installation Guide
If your openHAB setup does not support the JSON-based REST API for sending commands, you can configure a custom Webhook using the Webhook binding instead.
➡️ Continue here for setup instructions.
This section explains how to set up your openHAB sitemap for use with the app, outlines the supported Sitemap Widgets, and describes key aspects of the user interface.
Check the openHAB Sitemaps documentation to learn more about how sitemaps work.
➡️ openHAB Sitemaps Documentation
The sitemap name configured in the app must match the filename of the sitemap, excluding the .sitemap
extension.
For example, if the file is named garmin_demo.sitemap
, set the sitemap name in the app settings to garmin_demo
.
The label defined within the sitemap file is displayed in the app UI, such as in glances and other views.
sitemap garmin_demo label="My Home" {
}
The following element types are currently supported:
The following sections describe the supported parameters and the Sitemap Widget associated with each of these elements.
Frame
The Frame
element is used to group other elements, helping to organize your Sitemap Widgets into a hierarchical structure.
The app presents the sitemap using a menu-based structure. The root of the sitemap corresponds to the app’s home screen. Each Frame
is represented as its own menu, and Frame
elements can be nested within other Frames
to create submenus.
Important: The home screen and each Frame
may contain either only Frame
elements (i.e., submenus) or only non-Frame
elements (Switch
, Slider
, Text
, etc.). Mixing both types within the same Frame
is not supported.
Here is an example of a sitemap containing three Frame
elements.
sitemap garmin_demo label="My Home" {
Frame label="Entrance Gates" {
Switch item=EntranceGatesTrigger label="Open/Close" mappings=[OFF="GO", ON="DONE"]
Text item=EntranceGateStatus label="Status"
}
Frame label="Ground Floor" {
// ...
}
Frame label="First Floor" {
// ...
}
}
This configuration produces the following display in the UI:
![]() |
![]() |
Switch
The Switch
Sitemap Widget displays the state of an item and allows the user to change it.
Supported parameters:
label
: the label displayed in the UI.item
: the name of the associated openHAB item.mappings
(optional): used when commands other than ON
/OFF
should be sent.If no mappings
are provided, the widget will use the item’s command and state descriptions, which may come from the underlying channel or be manually defined via metadata. Command descriptions are used to label both the current state and the available command options (if multiple exist). If state descriptions are present, they take precedence for labeling the current state only—not for the list of selectable commands.
If neither mappings
nor command descriptions are available, the widget falls back to rendering a toggle switch, where selecting the item sends either an ON
or OFF
command.
If mappings
are provided, the widget displays the current state as text:
Selection behavior:
Example configuration:
Frame label="Switches" {
Switch item=Light_Switch label="Light"
Switch item=Heating_Switch label="Heating" mappings=[ON="ACTIVE", OFF="INACTIVE"]
Switch item=Rollershutter label="Shutters" mappings=[0="UP", STOP="STOP", 100="DOWN"]
}
In this example:
ACTIVE
or INACTIVE
, depending on the current state.UP
, STOP
, DOWN
).Resulting UI:
![]() |
![]() |
![]() |
![]() |
Notes:
Slider
The Slider
Sitemap Widget displays a numeric item state. When selected, it opens a full-screen view for picking a new value, which is then sent as a command.
Supported parameters:
label
: the label displayed in the UI.item
: the name of the associated openHAB item.minValue
: lower bound of the selectable range (default: 0
).maxValue
: upper bound of the selectable range (default: 100
).step
: interval between selectable values (default: 1
).releaseOnly
: if set, the new value is only sent when the selection is confirmed. Otherwise, values are sent immediately while scrolling.Important note:
While step=1
is consistent with openHAB’s default, it often results in too many steps (e.g., 100 steps for a range of 0–100), which is impractical for wearable interfaces. Increasing step
to 10
reduces the number of steps to 10, making interaction much more manageable.
Example configuration:
Frame label="First Floor" {
Slider item=Dimmer label="Dimmer" minValue=0 maxValue=100 step=10
// ...
}
Resulting UI:
![]() |
|
![]() |
![]() |
Note: Even button-based devices may support touch input, and on those, the UI reacts to both. On button-based devices, use up/down to scroll through the values, press enter (upper-right button) to confirm or back (lower-right button) to cancel. On touch-based devices simply tap the icons corresponding to the desired action or value to make a selection.
Behavior of releaseOnly
:
releaseOnly
: The value is only sent when the dialog is confirmed. Cancelling leaves the value unchanged.releaseOnly
: Values are sent immediately as the slider is moved. Confirming keeps the current value; cancelling reverts to the value before the dialog was opened.Text
The Text
Sitemap Widget is used to display the current state of an item without allowing any user interaction.
Supported parameters:
label
: the label shown in the UI.item
: the name of the openHAB item whose state should be displayed.This widget is ideal for showing read-only information, such as temperature, system status, or sensor readings.
Example configuration:
In this example, the Text
Sitemap Widget is used to display the status of entrance gates. Triggering the gates is handled by a separate Switch
element.
Frame label="Entrance Gates" {
Switch item=EntranceGatesTrigger label="Open/Close" mappings=[OFF="GO", ON="DONE"]
Text item=EntranceGateStatus label="Status"
}
Resulting UI:
![]() |
To access the settings menu:
The settings menu currently displays the app version and server URL. Additional features may be added in the future when the app evolves.
![]() |
![]() |
This section explains how the app handles errors and lists common issues you might encounter.
The app distinguishes between temporary (non-fatal) and critical (fatal) errors:
Non-fatal errors include:
Note: Non-fatal errors related to requesting the sitemap will become fatal if they persist for more than 10 seconds.
Immediately fatal errors include:
Certain communication errors when requesting the sitemap, specifically:
-1001
(see below)404
Note: Even after a fatal error, the app continues querying the sitemap. If a response is successfully processed, it returns to displaying the sitemap.
If “Suppress Empty Response Errors” is enabled:
When this option is enabled in the Settings, toast notifications for the following errors will be suppressed:
INVRES
– Invalid response (error code -400
)EMRES
– Empty responseHowever, if these errors persist for more than 10 seconds, they will be treated as fatal, and a full-screen error view will be shown.
To save space, communication errors shown in toast notifications follow this format:
X:NNNNNN
X
indicates the source of the error:
S
= sitemap pollingC
= command sendingNNNNNN
is the error code:
For a full list of Garmin SDK error codes, see the Constant Summary section here: ➡️ Garmin Communications API Docs
Special error codes:
The following error codes are used for common communication issues and those without specific error codes:
NO PHONE
– The watch is not connected to the smartphone (error codes -104
and -2
).INVRES
– The response was invalid (error code -400
).EMRES
– The response was empty.Error | Description |
---|---|
S:EMRES/myopenHAB |
myopenHAB currently has an intermittent issue where sitemap requests may return empty responses. The app will show a non-fatal S:EMRES notification. Usually, the next request succeeds, preventing escalation to a fatal error. More info |
This app is distributed under the MIT License.
Copyright (c) 2025 Robert Pollai
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The in-app iconography is attributed to the following sources:
Lightbulb by Adrien Coquet from Noun Project (CC BY 3.0)
Folder by Adrien Coquet from Noun Project (CC BY 3.0)
Settings by Adrien Coquet from Noun Project (CC BY 3.0)
Derived from:
Down by Adrien Coquet from Noun Project (CC BY 3.0)
Settings by Adrien Coquet from Noun Project (CC BY 3.0)
Derived from:
Chevron by Adrien Coquet from Noun Project (CC BY 3.0)
Check by Adrien Coquet from Noun Project (CC BY 3.0)
Cancel by Adrien Coquet from Noun Project (CC BY 3.0)