Announcing openHAB for Garmin

Version 0.2.4 just went live and:

  • Fixed a bug that prevented the sitemap label from displaying in Glance view

  • Improved performance of toggle switch updates, with a significant impact on overall update speed

View the full changelog

Just uploaded version 0.2.5.

Most of the changes in this release are internal and focus on improving the app’s handling of large sitemaps. Garmin Connect IQ apps are single-threaded, meaning that background processing—such as sitemap updates—can block the user interface. To address this, updates are now broken into small, asynchronous tasks managed by a task queue, allowing the app to remain responsive by processing other events between tasks.

One user-visible change affects the Slider widget on button-based devices: input hints are now styled to match Garmin’s native UI, providing a more consistent experience.

You can find the full changelog here:
View the full changelog

One more thing I almost forgot: if you’ve got yourself a shiny new Forerunner 570 or 970, good news — they’re now supported in the latest release!

so i have the app setup and i am running openhab 5.0 milestone. The app connects and downlaods the sitemap but i get a connection error on the watch anytime it trys to send a command.

I am connecting using myopehab.

The current milestone doesn’t include the required REST API changes, but soon (today or this weekend) there will be a new milestone release.

I am now looking at which features to implement next. Regarding the visibility, that is already working since nothing needs to be done on the client side. When the specified visibility condition is false, the element is not part of the sitemap JSON and thus not shown by the Garmin app.

I’ll add these information to the documentation.

I would suggest “Text under Text” to be implemented. On main screen we have possibility to Frames (in my case one of these is named Group ) which contains Text items(names of Groups) and next level of Text could show some information about members of that Group (in my case which windows are open). At the moment it works with Frames in Frames - openhab is yelling about that construction of sitemap but it works. Dont know if there are consequences somewhere on backstage :slight_smile:

Will test visibility today.

Thanks for your great work !!

I’m also using nested frames and haven’t encountered any issues so far. Where exactly do you see openHAB raising warnings about it?

I’m a bit conflicted when it comes to other container-like elements.

One limitation is that each menu item can only have a single action—it can either open a submenu or send a command, but not both. Group elements, for instance, would only be able to show the group’s state, but not allow toggling or control. On the other hand, text items with nested blocks seem to work without issues.

So compared to frames, the only real gain would be that the menu item opening a submenu could also show a state value.

Would you consider that a meaningful advantage?

That is what log-viewer shows about garmin.sitemap:

Openhab.core.model.core.internal.ModelRepositoryImpl	Validation issues found in configuration model 'garmin.sitemap', using it anyway: Frames must not contain other frames
sitemap garmin label="DTRV" {
	Frame label="Events" {
		Frame item=DateEventNextLeft label="Event"
			{
			Text item=DateEventNext label="Day"
			}
		Frame item=DateFamilyNextLeft label="Family"
			{
			Text item=DateFamilyNext label="Day"
			}
		Frame item=DateHolidayNextLeft label="Holiday"
			{
			Text item=DateHolidayNext label="Day"
			}
		Frame item=DateFriendsLeft label="Friends"
			{
			Text item=DateFriendsNext label="Day"
			}
	}



{here will attach pictures of watch display]

But if sitemap code changed to:

sitemap garmin label="DTRV" {
	Frame label="Events" {
		Text item=DateEventNextLeft label="Event"
			{
			Text item=DateEventNext label="Day"
			}
		Text item=DateFamilyNextLeft label="Family"
			{
			Text item=DateFamilyNext label="Day"
			}
		Text item=DateHolidayNextLeft label="Holiday"
			{
			Text item=DateHolidayNext label="Day"
			}
		Text item=DateFriendsLeft label="Friends"
			{
			Text item=DateFriendsNext label="Day"
			}
	}

then sitemap log-viewer does not return error BUT it is not possible to check the name of holiday. Display looks like this but can not click item to go inside

Sound fine for me.

Thanks for the examples! I wasn’t aware that a Frame can also be associated with an item. While that could be inferred from item being a common parameter, it’s not mentioned in the Frame specification or illustrated in any of the examples in the documentation.

I also didn’t find anything in the docs that explicitly states whether a Frame can or cannot contain other Frame elements—but there’s no example that shows this being done either.

I released version 0.3.0 today, but it seems to be stuck in the Garmin approval queue. Hopefully it’ll be available tomorrow—I’ll post the release notes once it goes live. This version includes a small fix related to visibility: after all, some adjustments were necessary to handle menu items becoming visible. Previously, they were always added to the end of the menu instead of being restored to their correct position.

Looking ahead, version 0.4.0 will focus on broader support for various sitemap elements. In the meantime, I’ve already implemented the color support you suggested—that’ll be included in 0.3.1. :slightly_smiling_face:

Version 0.3.0 is now available! This release finalizes performance improvements for larger sitemaps and includes two bug fixes along with several feature enhancements—see the details below.

View the full changelog

After all, some adjustments were needed to make the visibility parameter behave correctly. In previous versions, menu items that became visible were always added to the end of the menu. This is now fixed—items that become visible are inserted at their correct position in the list.

Another small change is that empty mapping entries are now supported for generic switches. This can be useful when the label of the sitemap element is already descriptive enough to explain the action being triggered.

Below is an example. The displayed entrance gate has a toggle switch—setting it to ON will trigger the gate operation, and it automatically resets to OFF after one second.

In this case, OFF is mapped to an empty string, and ON is mapped to “OK” to briefly indicate that the command was processed:

Switch item=Entrance_Gates_Power label="Open/Close" mappings=[OFF="", ON="OK"]

I’ve just uploaded version 0.3.2 of the app.

View the full changelog

Due to the delayed approval of version 0.3.0, I skipped 0.3.1 and jumped straight to 0.3.2. This release introduces two major new features:

Label and Value Color

You can now customize the color of labels and (text) status values. This allows for dynamic visual feedback, such as highlighting a sensor reading based on its state.

See the Label and Value Color section in the user manual for configuration details.

Here’s an example where the text state is color-coded based on its value:

Nested Elements

Nested sitemap elements are now fully supported. Refer to the Nested Elements section in the user manual for a complete overview.

Regarding state changes: it appears that the Basic UI implementation of sitemaps only allows nested elements under Frame and Text, and does not permit changing the state of the item associated with a Group element. Therefore, the fact that the Garmin app does not support state changes for menu items with nested elements is consistent with the Basic UI.

To improve navigation clarity:

  • A double-chevron now indicates that a menu item will open a submenu.
  • A single chevron continues to indicate that selecting the item will trigger a state change.

Here’s an example. The first screenshot shows a sitemap using only Frame elements. The second screenshot includes a Group element with a group of Switch items.
(Note: While the specification doesn’t allow mixing Frame elements with other types at the same level, this does work in practice.)


Version v0.3.3 brings support for additional sitemap elements.

View the full changelog

Highlights:

  • New Rollershutter widget
    A dedicated full-screen widget has been added for Rollershutter items.

  • Support for Setpoint element
    The Slider implementation aligns with how Setpoint is used in other UIs. As a result, Setpoint is now supported and handled by the same widget. The only functional difference is that Slider supports releaseOnly, while Setpoint does not.

  • Support for Selection element
    Selection elements are now supported and are handled the same way as Switch elements, since their behavior is identical to to the app’s existing generic Switch widget.

  • Documented support of Default elements
    Documentation has been updated to reflect support for the Default element. Since the openHAB server resolves Default to a specific type, no additional implementation was needed. However, only resolved types already supported by the app will work correctly.

Screenshots of the New Rollershutter Widget



It looks like the approval for version v0.3.3 is stuck again. Last time this was due to a Garmin server issue, and if that’s the case again, it might not be resolved until Monday. :roll_eyes:

Robert: I tried to add value of Group switched on items with %d, but it doesnt work as expected.

Switch item=LedG label="LED Group [(%d)]"
Switch item=LedG label="LED Group (%d)"

First line return label with value BUT value is exactly looking like [(3)] which means doubled brackets.
Second line returns label only without value - it looks (%d) literally

Hi Kristoph, thanks for the feedback!

I haven’t specifically tested patterns in labels and I’m not entirely sure how they’re intended to behave. My assumption is that pattern formatting should be handled by the server, which would return a fully formatted label string.

Could you send me your sitemap JSON so I can take a closer look? You can access it by visiting (assuming your openHAB instance uses the default port):

http://<server>:8080/rest/sitemaps/<sitemapname>

Feel free to post it in the GitHub issue I just created, or send it to me via direct message here in the forum.

Thanks for reply. Json gas been sent through direct message here.

Ps. What is causing error c415? I found it to be returned after trying to change state of one Switch (not the group switch mentioned above,it is different case) . That Switch worked before already. I am currently on 0.3.2 version.

Thanks, I responded also via direct message.

As a general explanation of these codes:

  • c indicates a command request,
  • s indicates a sitemap request.
    The number following the letter is the status code: positive values are HTTP error codes, while negative values (with a leading dash) are error codes from the Garmin SDK.

In your case, c415 refers to an HTTP 415 error — Unsupported Media Type.

For command requests, this usually means that the app is sending JSON, but the server doesn’t expect it. This often happens if the JSON API option is enabled in the app settings, but your openHAB instance doesn’t support it yet.

Could you check:

  • Whether this error occurs with all devices or only specific ones?
  • If the JSON API option is enabled in your app settings?
  • And whether the corresponding support is installed and enabled on your openHAB instance?

Let me know what you find and we can dig deeper if needed.

Error occurs on when trying to send any command(it worked week ago).
On Friday I updated(version 4.3.5 to 4.3.5 so nothing serious) OH through openhabian so maybe that action somehow modified or deleted Florian file for RestAPI? I’ll check that at home.

Json API is enabled in app settings.

What do you mean by “corresponding support” -Cloud connector?

By “corresponding support,” I meant Florian’s backport. Try re-installing it — it’s quite possible that the update overwrote the modified file. I haven’t done any updates myself since installing the backport, so I can’t say for sure, but this seems likely.

I looked into this more closely.

Your second example behaves as expected: formatting patterns for state display must be enclosed in square brackets. So (%d) is treated as literal text and isn’t interpreted as a formatting pattern.

The first example is more interesting. The app currently filters out the formatted state (in square brackets) and uses it exclusively for the Text element.

I tested this locally, and for me it works as intended. For example:

Switch item=TEST_SWITCH label="Light [(%s)]" icon=light

Displays like this:

Note on the side: as you can see, the next version will come with icon support.

So, first I’d like to understand what’s different in your setup. When you get a chance, please send me the raw JSON (as I mentioned in DM) so I can try to reproduce it. A photo of what you see in the app — particularly with the [(3)] rendering — would also help. And could you confirm that you’re using version 0.3.2? You can check that from the settings dialog in the app.

Secondly, this raises a design question. For toggle switches, it might actually be useful to show the formatted state next to the toggle. I’ll add this as a feature (ticket #150).

For the other widget types, the app already shows a text-based state:

  • For the Text widget, the formatted state from the sitemap is used directly.
  • For numeric widgets (Setpoint, Slider and Switch with Rollershutter items), I apply custom formatting to match the full-screen view, since I don’t have a full pattern parser available on-device. In the future, I might build one to align better with how openHAB UIs display these values.