Example and How-to: UI for Smartphone with MainUI

Design philosophy and intent

  • Smartphone-first: Build a user interface optimized for a phone screen, since 90%+ of our interaction with openHAB happens on a smartphone or tablet. (I have never understood the appeal of mounting a tablet on a wall when the same interface can be used freely throughout the room.
  • Family-friendly simplicity: Keep the UI simple and intuitive so it works well for the entire household
  • Standard, no-code approach: Build on MainUI using openHAB’s standard widgets and model only—with no or minimal custom coding or scripting.

Overview page:

The Overview page brings together the main functions and information I use daily in openHAB.

In addition, the overview page shows notifications using list items that appear only when specific conditions are met—for example, room temperatures that are too high or too low, the dishwasher status when running, or error messages from the heating system.

The bottom navigation includes the “Locations” and “Equipment” tabs. I have hidden the “Properties” tab that comes with the default installation because it makes the UI feel overloaded and more confusing—reducing rather than improving usability. (The same approach applies to the sub-menus under “Locations” and “Equipment,” where I also disabled the separate “Properties” tab.)

Semantic Model:

The “Locations” and “Equipment” tabs are driven by openHAB’s semantic model. Once the model is defined, these views are generated automatically.

  • Locations: I use our three floors as the primary locations (individual rooms felt too granular), plus Garage/Outdoor and Environment/Weather.
  • Equipment: Under the locations, I defined the following semantic equipment categories in the model tree: (1) lights, (2) roller shutters/blinds, (3) household appliances/white goods, (4) HVAC, (5) weather information, and (6) others.

(Note: Not all items need to be assigned in the semantic model—only those you want to appear in the UI on the Locations or Equipment pages.)

Tab „Equipment“:

To keep the UI compact and smartphone-friendly, I primarily use list items. For the relevant items in the semantic model, I added the “Default List Item Widget” in each item’s metadata.

Light:

I use dimmers throughout the house, with only a few exceptions. For that reason, I model most lights as item type Dimmer. Pulling the dimmer to zero turns the light off. As icon, I use the standard openHAB light icon (oh:light), which updates dynamically based on the dimming level.
For lights with color temperature, I decided to add a separate setpoint item and configure it as Stepper List Item in the item’s Default List Item Widget metadata. (There are other ways to represent color temperature, but I found dimmer-based controls confusing because I use dimmers strictly for brightness adjustment.)

Rollershutters:

Roller shutter items use the default Default List Item Widget „oh-rollershutter-item“ and the standard icon oh:blinds.

HVAC / Heating:

For heating, I added only the temperature setpoint items to the semantic model. In the Default List Item Widget, I select Stepper List Item. I display the current room temperature and humidity (entered as expression in the “After” of the Default List Item Widget).

The base icon is oh:heating, and the visualization is linked to the actual valve actuator status. Thus, the icon indicates if the heating valve is currently fully open or closed.

Overall, this approach gives me a compact list with the key controls and information visible on a single page.

(One note to item values: Sometimes item values in openHAB are initially not formatted the way you want. By adding the “State Description” metadata to an item, you can control how the value is shown in displayState. Use the “Pattern” field—for example, set %.1f to display a numeric value with one digits after the decimal point.)

Tab „Location“:

The Location tab sorts the same items by location and is generated automatically by openHAB. The visual representation of each item is identical to the Equipment tab, and the content is again presented in a compact list format.

(Side note on floorplans: I experimented with them because they often create a “wow” effect. However, I quickly found that floorplans are largely a visual gimmick with little practical value—the information and controls are not well organized and are awkward to use in day-to-day operation.)

Quick access pages in the sidebar:

I added three pages to the sidebar for quick access to specific functions (Sidebar & Visibility → Show on sidebar). In my setup, these are:

  • A page with all heating-related items
  • A page to control our roof windows
  • A page that lists all lights currently turned on (using conditional visibility)

For conditional visibility of light items on the page, I add an expression like the following to the list item YAML, which hides a light item, when the light is turned off:

visible: =items.DGFlur_Light.state==“0”?“false”:“true” ).

Conclusion:

Overall, MainUI works very well. It is flexible and—by leveraging the semantic model and item metadata—automates much of the work of building and maintaining the UI. After more than two years of daily use, I can highly recommend it, and my family agrees.

1 Like

The only thing I would add if compactness is your goal, with just a little more work, you can create default list item widgets that combine the display and control of multiple Items in one widget.

For example,

This combines the status of the deadbolt and the contact sensor and lets me unlock the deadbolt all on one row. You can find this widget on the marketplace.

A more ambitious multi-Item widget is the one I created for my smart humidifiers.

That widget combines eight separate Items.

Though to be honest, no one in my family actually uses MainUI for anything (including me). Everything is automated so the home just does what it needs to when it needs to and, in those rare cases where something does need to be controlled manually we use the smart speaker or wireless buttons. But I like the challenge of creating a more complicated custom widget.

An oh-repeater widget is handy for this sort of thing. You can pull all the Items with a given tag, type, metadata, members of a Group and create a widget with them all. If you add or remove something the widget adjusts automatically. For example, my lighting control widget:

But if I turn on “Tis the Season” I have more lights to control. The widget adjusts automatically.

I use the same approach for my battery and services status widgets. they only show the low batteries or services that are offline.

The latter two widgets are on the marketplace, as is the door widget above.