Add UI section (#1464)

Add several pages related to UI.
Move sitemaps, HABPanel to it.
Rename "User Interfaces & Ecosystem" to "Ecosystem".
Rename "Beginner Tutorial" to "Getting Started".
Put the installation guide above the Concepts section.

Also fix https://github.com/openhab/website/issues/270.

Signed-off-by: Yannick Schaus <github@schaus.net>
pull/1483/head
Yannick Schaus 2021-02-05 16:15:35 +01:00 committed by GitHub
parent fbf6db6cc4
commit f5c7ad70e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 834 additions and 56 deletions

View File

@ -8,10 +8,11 @@ def add_placeholder_pages()
"docs/apps/android.md",
"docs/configuration/habpanel",
"docs/configuration/iconsets/classic",
"docs/configuration/ui/habmin",
"docs/configuration/ui/habot",
"docs/configuration/ui/basic",
"docs/configuration/ui/classic",
"docs/ui/components",
"docs/ui/habpanel",
"docs/ui/habpanel/habpanel.md",
"docs/ui/habot",
"docs/ui/basic",
"docs/ecosystem/alexa",
"docs/ecosystem/google-assistant",
"docs/ecosystem/ifttt",

View File

@ -7,7 +7,7 @@ module.exports = [
]
},
{
title: 'Beginner Tutorial',
title: 'Getting Started',
collapsable: false,
children: [
['tutorial/', 'Tutorial Overview'],
@ -26,18 +26,6 @@ module.exports = [
'tutorial/example'*/
]
},
{
title: 'Concepts',
collapsable: false,
children: [
['concepts/', 'Concepts Overview'],
'concepts/things',
'concepts/items',
'concepts/discovery',
'concepts/audio',
'concepts/units-of-measurement', // from v2.3 onwards
]
},
{
title: 'Installation Guide',
collapsable: false,
@ -55,15 +43,27 @@ module.exports = [
['installation/security', 'Security']
]
},
{
title: 'Concepts',
collapsable: false,
children: [
['concepts/', 'Concepts Overview'],
'concepts/things',
'concepts/items',
'concepts/discovery',
'concepts/audio',
'concepts/units-of-measurement', // from v2.3 onwards
]
},
{
title: 'Configuration Guide',
collapsable: false,
children: [
['configuration/', 'Configuration Overview'],
'configuration/editors',
'configuration/addons',
'configuration/things',
'configuration/items',
'configuration/sitemaps',
'configuration/persistence',
'configuration/rules-dsl',
'configuration/transformations',
@ -72,22 +72,34 @@ module.exports = [
'configuration/jsr223',
'configuration/services',
'configuration/multimedia',
['configuration/restdocs', 'REST API'],
['configuration/apitokens', 'API Token Generation'],
['configuration/migration/', 'Migration from openHAB 2']
]
},
{
title: 'Interfaces and Ecosystem',
title: 'User Interface Guide',
collapsable: false,
children: [
'configuration/editors',
['configuration/ui/habot/', 'HABot'],
'configuration/habpanel',
['configuration/ui/basic/', 'Basic UI'],
['configuration/restdocs', 'REST API'],
['configuration/apitokens', 'API Token Generation'],
'ui/',
'ui/sitemaps',
'ui/layout-pages',
'ui/map-pages',
'ui/floorplan-pages',
'ui/tabbed-pages',
'ui/chart-pages',
['ui/building-pages', 'Building Pages'],
['ui/components/', 'Component Reference'],
'ui/habpanel/habpanel',
['apps/android', 'Android App'],
'apps/ios',
'apps/windows',
'apps/windows'
]
},
{
title: 'Ecosystem',
collapsable: false,
children: [
['ecosystem/alexa/', 'Amazon Alexa'],
['ecosystem/google-assistant/', 'Google Assistant'], // from v2.3 onwards
['../addons/integrations/homekit/', 'Apple HomeKit'],

View File

@ -95,15 +95,13 @@ def process_main_docs(docs_source_dir)
puts ">>> Migrating the UI section"
Dir.glob("#{docs_source_dir}/_addons_uis/**") { |path|
next if path =~ /habpanel/ || path =~ /paper/ # Those already have their own article, no need to include the readme...
addon = File.basename(path)
puts " -> #{addon}"
FileUtils.mkdir_p("docs/configuration/ui/" + addon)
process_file("#{docs_source_dir}/_addons_uis", addon + "/readme.md", "docs/configuration/ui", "")
puts " -> images (#{addon})"
FileUtils.cp_r("#{docs_source_dir}/_addons_uis/#{addon}/doc", "docs/configuration/ui/#{addon}") if Dir.exists?("#{docs_source_dir}/_addons_uis/#{addon}/doc")
Dir.glob("#{docs_source_dir}/ui/*.md") { |path|
file = File.basename(path)
puts " -> #{file}"
process_file("#{docs_source_dir}/ui", file, "docs/ui", "#{$docs_repo_root}/ui/#{file}")
}
puts " -> images"
FileUtils.cp_r("#{docs_source_dir}/ui/images", "docs/ui/images")

View File

@ -1,16 +0,0 @@
---
layout: documentation
title: Configuration though HABmin
---
{% include base.html %}
# Configuration through HABmin
HABmin is a modern, professional and portable user interface for openHAB,
providing both user and administrative functions (eg sitemaps for users, and configuration utilities
to aid setup).
Please refer to the [HABmin Addon documentation]({{docu}}/addons/uis/habmin/readme.html).
{% include contribution-wanted.html %}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -18,7 +18,6 @@ In order to represent all of these, openHAB defines the following base component
- [Things](things.html) - Your devices represented in openHAB
- [Items](items.html) - properties and capabilities of your Things
- [Groups](items.html#groups) - collections or categories containing Items
- [Sitemaps](sitemaps.html) - User-defined frontend interfaces to arrange Groups, Items and more
- [Transformations](transform.html) - Helper functions to transform your data
- [Persistence](persistence.html) - Services to store data over time
- [Rules](rules-dsl.html) - Automation logic, the "smart" in your Smart Home!
@ -27,6 +26,12 @@ In order to represent all of these, openHAB defines the following base component
The individual articles have all the details needed to understand the concepts behind these building blocks for your Smart Home.
For more details on the basic concepts behind openHAB, please visit the [Concepts Overview page](/docs/concepts/index.html).
::: tip
This section does not cover building user interfaces; this subject has its own section: [User Interfaces](/docs/ui/)
:::
## Versatility
openHAB 3 provides a _single_ graphical user interface to modify settings, to manage your components and rules, and to provide a UI for users.

View File

@ -20,11 +20,7 @@ h1.welcome {
<img src="/openhab-logo-square.png" width="150" height="150" class="intro-logo" />
<h1 class="welcome">
# Welcome!
</h1>
<h1 class="welcome">Welcome!</h1>
The **open H**ome **A**utomation **B**us (openHAB, *pronounced ˈəʊpənˈhæb*) is an open source, technology agnostic home automation platform which runs as the center of your smart home!

350
ui/building-pages.md Normal file
View File

@ -0,0 +1,350 @@
# Building Pages: Components & Widgets
[[toc]]
## UI Components: introduction and structure
**UI components** are the basic building blocks for many UIs in openHAB 3.
The Main UI Pages and Personal Widgets are notable UI components, but Sitemaps that were created in the UI and HABPanel dashboards are as well.
These structures make up hierarchies that notably define the pages in their entirety are relatively simple:
Each component has:
- A **type**
- Most of the time, a set of **configuration properties**
- Optionally, a set of **named slots** which hold collections of more components. By putting components into slots, we therefore define a hierarchy.
Slots are optional, and have a name; usually when theres slots involved theres a `default` slot but not always.
The semantics of both the config properties and the slots depend on the component type, as well as the allowed sub-component types in the slots.
The Component Reference provide details on what you can put in a certain component's config & slots.
Sometimes, the slots can be seen as different placeholders within a component where new components may be added. For instance, cell widgets have a `header` slot which represents the part of the cell when not expanded.
The `default` slot is the space in the cell which becomes visible when the cell is expanded.
In various parts of the UI page designers you can "focus" on a particular component usually by selecting the **Edit YAML** item in a black context menu.
Below is a typical component as represented in YAML:
```yaml
component: oh-type
config:
prop1: value1
prop2: value2
prop3: =expression
...
slots:
default:
- component: ...
config: ...
slots: ...
- component: ...
anotherSlot:
- component: ...
...
...
```
## Root Components & Props
At the top of the component tree theres we can find a **root component**.
Pages are examples of root components.
They have additional attributes:
```yaml
uid: component1
props:
parameterGroups:
- name: group1
label: Property group
...
parameters:
- name: prop1
label: Prop 1
type: BOOLEAN
groupName: group1
description: What prop1 does
- name: prop2
label: Prop 2
type: TEXT
context: item
description: Choose an item for this prop
- name: prop3
type: NUMBER
advanced: true
...
tags: ["tag1", "tag2"]
component: ...
config: ...
slots: ...
```
- an **uid** (its Unique IDentifier)
- a **props** structure describing its own properties; props define parameters and parameter groups following a subset of the configuration description schema found in bindings, services and throughout openHAB: see [Configuration Descriptions](/docs/developer/bindings/onfig-xml.html)
- a set of **tags**
## Widgets: Definition & Usage
Widgets are nothing more than discrete components that can be added to a Page.
No matter which type of page youre editing, the designer will feature black buttons beside most widgets, that open a contextual menu for the widget in question.
These menus will in most cases allow you to:
- configure the documented parameters with a config sheet (“Configure Widget” or similar)
- open the part of the pages YAML representation pertaining to the widget (“Edit YAML”), that is, a subgraph of the pages component tree with that widget as its root component
- perform cut/copy/paste operations, if supported (you can only do that in the same page currently, to copy or move widgets between pages, you may use the YAML view)
- reorder the widget within its parent slot (these options are usually named “Move Up” and “Move Down” although you may occasionally encounter other labels, like “Move Left”/“Move Right”)
- remove the widget
Configuring the widget with the config sheet is of course more user-friendly than editing the YAML, as the options are usually organized logically in groups and feature a description:
![Configuring a Widget](./images/widget_config_sheet.png)
However, it's important to know that there are limitations and sometimes editing the YAML directly will be best, because:
1. not all options are described, since widgets are often wrappers for a similar concept in the library it's based on, either Framework7, ECharts, Leaflet, or other specialized libraries.
This means that in these cases, these underlying concepts will usually be passed the key/values of the (openHAB) widget component's config so that more parameters can be accepted than those which are documented in the widget's definition.
Sometimes it will be indicated somewhere when configuring the widget, or in the openHAB documentation itself, on the other hand some options won't be available for use (for instance, because they expect a callback function and you cannot define those in the widget's config) or need some transformation.
1. Sometimes you'll want to use an expression to configure the property, but the UI will get in your way - for instance, it will display an item picker while your intention is to set the prop value to be `=props.item1`.
See below to learn more about expressions.
1. To quickly and efficiently duplicate similar widgets with only a few differences, it is always way easier to copy/paste the relevant YAML in the editor.
1. The YAML is the best way of sharing complete or partial component structures like pages or widgets with others in the forum.
Besides, there are several options that virtually all widgets in layout pages, map pages and plan pages accept, all of which are not currently available in the config sheet:
- `visible`: you can specify a `false` boolean to this option to hide the widget. This powerful feature, combined with expressions (see below), allows you to dynamically show widgets or even entire sections (if you use it on layout widgets containing other widgets), depending on the state of your items
Example: `visible: =items.TV_Powered.state === 'ON' && items.TV_Input.state === 'HDMI1'`
- `visibleTo`: this accepts an array of strings like `role:administrator`, `role:user`, or `user:<userid>`, allowing the widget to be only visible to specific users or those with a certain role.
Example: `visibleTo: ["user:scott", "role:administrator"]`
- `class` and `style` are [standard Vue.js attributes](https://vuejs.org/v2/guide/class-and-style.html) and can be used to either alter the CSS classes or add inline styling to the component.
See "Styling" below.
### Types of Widgets
To help you define usable pages, there are a number of built-in widgets that you can use - most of which will be in layout pages. Those built-in widgets revolve around several libraries:
- the **System** library includes "crude" controls that you cannot add with the designers - for instance `oh-button`, `oh-slider`, `oh-colorpicker`. Instead, you're more likely use them within some container (card, list item...) provided by a widget of the Standard library; but when designing a personal widget with a complex layout you may want to use one or several of them directly. You may also use them in a slot of another widget, for those which define some, in order to add additional controls to that widget.
- the **Standard** library, which has several classes of widgets:
- **layout widgets**, examples: `oh-block`, `oh-masonry`, `oh-grid-row`, `oh-grid-col` that you usually add with the designer to a layout page
- **standalone widgets**, examples: `oh-label-card`, `oh-slider-card`, `oh-player-card` - usually not much more than widgets from the System library wrapped in a card
- **list item widgets**, examples: `oh-list-item`, `oh-stepper-item`, `oh-toggle-item` - widgets that are thinner than the standalone ones, which you can only add a part of a list (`oh-list` or `oh-list-card`)
- **cell widgets**, examples: `oh-cell`, `oh-knob-cell`, `oh-colorpicker-cell`: these widgets are fixed-size cells that you can only add to a `oh-cells` container widget immediately below a `oh-block` in a layout page - they will either perform an action - switching a light on & off - or expanding to reveal additional controls
- **page-specific widgets**, for instance map pages have `oh-map-marker` or `oh-map-circle-marker`, charts have different types of widgets than the rest to represent axes, series etc.
See the [Component Reference](./components/) for details about the different libraries of components.
## Dynamically Configuring Components with Expressions
Virtually everywhere - with the notable exception of chart pages - every time you need a config prop to be dynamically updated, you can use an expression to configure it.
Expressions are string literals beginning with the symbol `=` and everything after it is evaluated using a syntax very similar to JavaScript, you can use arithmetic or string operations etc., the [conditional (ternary) operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator), as well as the following objects (subject to evolutions):
- `items` is a dynamic key/value dictionary allowing you to retrieve the state of items; the result of `items.Item1` will be an object like `{ state: '23', displayState: '23 °C' }` (`displayState` may be omitted). You can therefore use `items.Item1.state` to use the current state of Item1 in your expression, if it changes, it will be reevaluated
- `props` is a dictionary of the key/values of self-defined props for the current personal widget, or page (pages, like any root UI components, may indeed have props). It is indispensable to use props in expressions when developing a personal widget
- `vars` is a dictionary of variables (see below) that are available in the component's context
- `loop` is a dictionary containing iteration information when you're repeating components from a source collection, it is defined only when in the context of a `oh-repeater` component
- the JavaScript `Math` object (so you can use `Math.floor(...)`, `Math.round(...)` and the like)
- the JavaScript `JSON` object to parse or produce JSON;
- `dayjs` to build instances of the [day.js library](https://day.js.org/docs/en/parse/now) that you can use to parse or manipulate date & time
- `theme` which holds the current theme: `ios`, `md` or `aurora`
- `themeOptions` and `device` allow to use the relevant objects that you can see in the About page, Technical information, View details, under `clientInfo`
Expressions are particularly useful in cases where one wants to combine the states of more than one Item, or use the state of more than one Item in a single widget element.
For example, the icon of an Item can be based on the state of a different Item.
### Examples
```js
=(items.Color1.state.split(',')[2] !== '0') ? 'On ' + '(' + items.Color1.state.split(',')[2] + '%)' : 'Off'
```
Translates the third part of the HSB state (brightness) of the Color1 item to On or Off.
```js
icon: =(items[props.item].state === 'ON') ? 'f7:lightbulb_fill' : 'f7:lightbulb'
```
Use a filled icon of a lightbulb but only if the state of the items passed in the prop `item` is ON.
```js
= (items.xxx.state === '0') ? 'Off' : (items.xxx.state === '1') ? 'Heat' : (items.xxx.state === '11') ? 'Economy Heat' : (items.xxx.state === '15') ? 'Full Power': (items.xxx.state === '31') ? 'Manual' : 'Not Set'
```
Stacked ternary statements to translate a value to a description.
```js
=dayjs(items.DateItem.state).subtract(1, 'week').fromNow()
```
Substracts one week from the state of `DateTime` and return a relative time representation in the current locale ("3 weeks ago").
### Debugging Expressions
Expressions can be tested in the Widgets Expression Tester found in the Developer Sidebar
(<kbd>Shift+Alt+D</kbd>).
## Actions
When configuring a widget, you will encounter options related to actions (usually, when something is clicked or touched, but there might be several actions configured for a single widget, for instance, clicking on different parts or a long tap with a touch device); regardless, they will all have the same options:
![Actions](./images/widget_actions.png)
These action options allow you to configure the interactivity within your pages, as well as the relation between them, in an extensive way. You can navigate to another page, display additional controls, popups and other modals, send commands to items every time a widget allows you to choose an action.
For instance, a floor plan marker might either open another page in a popup, or toggle an item.
Configuring the action type reveal more options in the action sheet:
![Action Configuration](./images/widget_action_configuration.png)
### Types of Actions
Action | What it does
-|-
Navigate to page | Opens a different Page with an optional transition.
Send command | Issues a command to an Item.
Toggle Item | Alternate an item between two states by sending commands (regular command if the item's state is different, or an alternative command if the state is equal to the regular command). Typically used with ON/OFF.
Command options | Issues a command to the configured Item based on a comma-separated locally-defined list of options, or on the Item's State Description.
Run rule | Trigger a rule directly.
Open popup | Open a Page or personal widget in a popup which will be displayed fullscreen on phones and in a 630x630-pixel modal dialog on larger screens.
Open popover | Open a Page or personal widget in a small "callout" comic-like bubble
Open sheet | Open a Page or personal widget in a drawer appearing from the bottom of the screen.
Open photo browser | Displays a full screen interface to view one of several images
Group details | Used with Group items to open a popup with an automatically-generated list of the members of the group, represented by their default list item widget. For Groups with a base type like Switch, a standard card widget will also be shown for the Group itself.
Analyze Item(s) | Opens the Analyzer window for the specified item(s) and period
External URL | Open an external web page
Set Variable | Set a variable that you can use in other parts of the page or widget.
::: tip
In your own personal widgets (see below), you can define a parameter group with an `action` context to automatically define implicit props that you can pass "en masse" to built-in components that accept actions with the `actionPropsParameterGroup` property:
```yaml
props:
parameterGroups:
- name: myaction
label: My Action
context: action
...
component: oh-button
config:
actionPropsParameterGroup: myaction
```
:::
## Variables
Varibles are a way to allow more complex scenarios in pages & personal widget development.
Variables can be used using several methods:
- the `variable` config parameter of `oh-gauge` (read-only),
`oh-input`, `oh-knob`, `oh-slider`, `oh-stepper`, `oh-toggle`
will accept a variable name and control it instead of
sending commands to items if set.
The "item" parameter can
still be set to set the widget to the item's state, when
the variable has no value.
- the `vars`object available in expressions (for example
`=vars.var1` will evaluate to the value of the variable `var1`.
- the `variable` action allows to set a fixed or computed
(using an expression) value to a variable.
`oh-button` & `oh-link` have a special parameter `clearVariable`
which allows to unset a version when clicked, after performing
the action.
This is useful when "validating" a variable e.g.
send a command to an item with the variable value then reset it.
## Techniques for Styling Widgets
### Predefined CSS Classes
As seen before, you can use CSS classes in the `class` property (as an array) or set CSS properties in the `style` property (as a dictionary) on your components.
You cannot define new CSS classes, but you can use classes from Framework7, for instance:
- [Typography](https://v5.framework7.io/docs/typography.html)
- [Color Themes](https://v5.framework7.io/docs/color-themes.html#apply-color-themes)
- [Hairlines](https://v5.framework7.io/docs/hairlines.html)
- [Elevation](https://v5.framework7.io/docs/elevation.html)
### CSS Variables
Another interesting technique is to override the many [CSS Variables](https://v5.framework7.io/docs/css-variables.html) defined by the framework to suit your particular component's needs.
The override will be applied to all descendants in the HTML DOM tree, in case of the Framework7 variables the underlying components which use them will use the new value.
It is recommended to use Framework7 CSS variables in your components too, when appropriate, so that way you'll be sure the properties change according to the current theme and dark mode setting.
To redefine a CSS variable for the component and its descendants, use this syntax:
```yaml
style:
--f7-button-border-color: rgb(255, 0, 0)
```
To reuse a CSS variable, use:
```yaml
border-color: var(--f7-button-border-color)
```
You can even define your own CSS variables and use them in your components:
```yaml
config:
style:
--my-color: =props.color
slots:
...
...
...
config:
style:
background-color: var(--my-color)
```
### Applying CSS Properties Directly
Applying CSS properties like `border-color` directly on components is sometimes enough; but contrary to CSS variables like `--f7-button-border-color` which will be inherited to descendants in the tree, either by your own components or by f7 components (or their OH derivatives) that make use of these variables, they will only work on the element where you put the style configuration.
There are hundreds of [CSS properties](https://www.w3schools.com/cssref/) you can use to design your widgets. Use the resources at [W3Schools](https://www.w3schools.com/css/default.asp) to learn more about CSS techniques - these examples will provide code in HTML and classes definitions but you can most of the time adapt them for usage in components' YAML definitions.
While the Layout components (`oh-block`, `oh-grid-row`, `oh-grid-col`) can help you with the placement of your widgets, to lay out sub-components _within_ a widget, you shouldn't use them because they include design mode controls that you don't need.
While can use their `f7-block`, `f7-row` and `f7-col` equivalents instead, in many cases this is still "overkill": consider applying directly the Flexbox or Grid properties to the components.
These resources will help you with Flexbox and Grid:
- [A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
- [justify-content "Play it"](https://www.w3schools.com/cssref/playit.asp?filename=playcss_justify-content&preval=flex-start) and others found in the reference
- [A Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid/)
- [Grid Tutorial on W3Schools](https://www.w3schools.com/css/css_grid.asp)
## Personal Widgets
You can extend the library of widgets you have at your disposal by creating personal ones, either by yourself, or copy-pasting from examples by the community; then you can reuse them on pages, multiple times if need be, simply configuring their props to your needs.
To add a new personal widget, as an admin, go to **Developer Tools > Widgets**, then use the '+' button to create a new one.
The view features a code (YAML) editor and a live preview, you can change the orientation with the button in the center of the bottom toolbar.
::: warning WARNING
Don't forget to change the `uid` right away because you won't be able to alter it afterwards.
:::
Sometimes the live preview will fail to update, you may want to hit the Redraw button or <kbd>Ctrl-R</kbd>/<kbd>Cmd-R</kbd> regularly when designing your widget.
To actually see how the config sheet would look like, and specify props for your widget for the live preview, click on Set props (<kbd>Ctrl-P</kbd>) and configure them as needed.
After saving the widget, you will have it as an option (under "Personal widgets") to add it to a layout page, or display in a modal like a popover, or use it as the default representation of an item.
Note the special `widget:<uid>` syntax for the component type to specify "use this personal widget here", the `config` being the value to wish to assign to the widget props:
```yaml
component: widget:widget_0a26c10a4d
config:
prop1: Test
item: Color1
```

64
ui/chart-pages.md Normal file
View File

@ -0,0 +1,64 @@
---
title: Chart Pages
---
# Chart Pages
Chart Pages can display historical values in a full-screen `oh-chart` component.
![Chart Example](./images/chart_example.png)
## Anatomy of a Chart Page
Charts are based on the Apache ECharts library.
The [Cheat Sheet](https://echarts.apache.org/en/cheat-sheet.html) on EChart's website offers an interactive illustration of the concepts used in it.
The openHAB UI currently supports only a subset of those:
- Series: Bar, Line, Pie, Heatmap, Scatter, Gauge
- Coordinates: Grid, Calendar
- Other Components: Title, Legend, Tooltip, MarkPoint, MarkLine, MarkArea, DataZoon, VisualMap, Toolbox
The `oh-chart` and `oh-chart-page` normally configure charts using components such as `oh-grid`, `oh-time-series`, `oh-value-axis`, and others, placed in the appropriate slots.
See their documentation for more details.
Additionally, you can merge raw options as they're defined in ECharts in the root `options` parameter.
## Building a Chart Page
### From the Analyzer
Throughout the UI you may encounter places where you can click a widget to call the Analyzer window, which lets you build a chart of one or several item(s) persisted data and change some settings with simple controls.
Sometimes you'll get a result that you like and would like to save.
You can do exactly that: use the Save button on the title bar on the right, give it an identifier, and it will be saved as a Chart Page.
You can then customize it further from the Chart Page Designer.
::: tip TIP
Once you've saved the Analyzer result as a Chart Page, you can display this page like you would any other, but the controls that you used to configure the chart in the Analyzer will not be available.
Chart Pages cannot be configured by the user (except changing the period, zooming, or by using the toolbox).
You can, however, launch the Analyzer with a predetermined set of item(s), chart type and period with the "Analyze" widget action.
:::
### From the Chart Page Designer
From the Pages section in Settings, click "+" then Create Chart, or choose an existing Chart Page, to bring up the Chart Page Designer.
You can choose the period type and initial period in the Page Configuration section, and then add **Coordinate Systems**, **Axes**, **Series**, and **other chart components**.
Usually, you will first add a **Grid**, then either directly one or more **Time Series** (default axes will be created for you), or first Axes and an **Aggregate Series**.
When doing aggregations, you have to be careful to add the right type of axes based on the period that you chose (Aggregate Series don't support Dynamic period as chart type).
Examples:
- For bars representing hourly aggregates, use a value Y axis and a category axis configured as "Hours of day".
Then click Add Aggregate Series, choose the item, the Bar type, and "Hour of Day" as first dimension.
- For a 2-dimension heatmap representing hours for an entire month, add a category Y axis configured as "days of month" and a category X axis configured as "hours of day".
Then click Add Aggregate Series, choose the item, the Heatmap type, "Day of Month" as first dimension, "Hours of Day" as second dimension.
Since the "outer" (first) dimension is on the Y axis, make sure you also enable "Transpose" to reflect that fact.
Lastly, also make sure you add a Visual Map component to the chart since the Heatmap needs one as its color scale - even if it's hidden.
In the **Other Components** section you will have badges in the buttons representing the number of components of that type.
You can indeed add several of these components, when appropriate.
Below the title bar of the dialog to edit the component type, use the "+" tab to add one more, or use the Remove button at the bottom to remove the currently displayed component.

34
ui/floorplan-pages.md Normal file
View File

@ -0,0 +1,34 @@
---
title: Floorplan Pages
---
# Floorplan Pages
Floorplan Pages can display markers or other elements over a custom image of your choice that you can zoom & pan.
![Floorplan Example](./images/floorplan_example.png)
## Anatomy of a Floorplan Page
Floorplan pages have some configuration properties that you mostly can define in the Design mode.
You can also add markers on it.
Markers can display an icon, and a tooltip either when they're hovered on, or clicked/tapped, and also perform an action.
With the `useTooltipAsLabel` property, markers can also be a text label directly displayed over the background - without the icon.
The `tooltipStyles` property can be configured in YAML to set additional CSS properties to the tooltip/label.
## Building a Floorplan Page
In the Design view, configure the properties below Page Configuration.
To add markers, you can do it either:
- in Design mode under Markers: click **Add marker**, then click on the newly added entry to configure the marker.
Using the black context menu, you can reorder or remove existing markers.
- in Run mode: click **Add marker** and drag the new marker to the desired position.
While it's "selected", a popover toolbar will appear, allowing you to configure it, edit its YAML, copy it (a Paste button will then appear besides **Add Marker**), or remove it.
To position markers accurately, it's usually best to do it in Run mode, while the Markers area in Design mode is best for an overview of the markers on the page.

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
ui/images/chart_example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
ui/images/map_example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

BIN
ui/images/responsive1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
ui/images/responsive2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 133 KiB

View File

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 973 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

157
ui/index.md Normal file
View File

@ -0,0 +1,157 @@
---
title: User Interface Design Overview
---
# User Interface Design Overview
Following the previous sections, you should have a working installation, with several Things, Items and Rules.
You also ideally built a model to represent your home, and can succesfully operate your items individually within the administration area.
You may now want to present them a little more nicely, to yourself or your family members, so they can interact with them or check their status easily without requiring access to these administration screens.
To do that, openHAB puts different options at your disposal; they are commonly referred to as **Pages**.
## Types of Pages
Several types of pages are available:
### The Home Page
The main's UI **home page** consists of 4 tabs:
- an overview which you can customize entirely from scratch;
- 3 tabs representing a generated view of your model oriented by **Location**, **Equipment** and **Properties**.
In these 3 model-oriented tabs, expandable cards will appear **automatically** as you build your model, allowing you to get different perspectives on your home.
For instance, you may want to see everything in a particular location, or everything pertaining to a certain class of equipment, like heating, or see a consolidated view of all items related to a certain property like temperature or humidity.
Clicking on the card will make it expand and reveal its contents.
Some of these cards will also feature glance badges that will extract some predefined information from your model and display it without you having to open the card.
### Sitemaps
[**Sitemaps**](./sitemaps.html) are hierarchies of pages and sub-pages that are comprised of simple controls from a well-defined, limited set.
They have existed in openHAB since its first versions, therefore you will probably encounter a lot of examples referring to them throughout the documentation and in the older community discussions.
As they have less customization options than the other types of pages, notably as compared to the more powerful layout pages, they are also arguably easier to learn.
You can define them either in configuration files, with a special textual syntax, or in the Pages section of the administration area; however, **be aware that the main web UI is not currently able to display them**.
Fortunately, there are however several other mature apps, notably the mobile apps for Android and iOS devices, but also Basic UI for the web, which are primarily dedicated to rendering sitemaps.
### Layout Pages
[**Layout pages**](./layout-pages.html), introduced in openHAB 3, are the most common and versatile way of displaying information in the main UI.
They have extensive options to control how they are laid out, and can display [**Widgets**](./building-pages.html) coming from the built-in libraries or widgets that you have designed or imported in your personal library.
### Maps & Floorplans
[**Maps**](./map-pages.html) and [**Floorplans**](./floorplan-pages.html) are Pages dedicated to displaying markers and other elements on a background overlay.
In case of floorplans, the background will be a custom image defined by you; in case of maps, it will be a zoomable view of the world from a provider service, either an actual map layer or a satellite view, centered on the markers that you defined.
### Charts
[**Chart**](./chart-pages.html) pages are meant for interactive visualization of persisted data in the main UI.
Options include displaying time series, aggregates, heatmaps, calendars, with the ability to select the period and date to show.
You can either start them from scratch by creating a new Chart page from the Pages section, or, when in the Analyzer, you can save the result of a analyzing session to a chart page for further customization and retaining the current view.
### Tabbed Pages
[**Tabbed Pages**](./tabbed-pages.html) are Pages used to combine several other Pages and render them in tabs.
You simply configure the Pages that you wish to show, choose a few details about the tabs themselves (label, icon...) and can then consider the result as a single Page.
### Summary
The table below summarizes the different types of Pages and their compatibility:
|Type|Designed in|Viewed in|Stored in|
|----|-----------|---------|---------|
|Home|main UI|main UI|JSON DB|
|[Sitemap](./sitemaps.html)|main UI or `.sitemap` file|Basic UI, iOS/Android apps and others|Configuration folder or JSON DB|
|[Layout](./layout-pages.html)|main UI|main UI|JSON DB|
|[Map](./map-pages.html)|main UI|main UI|JSON DB|
|[Floorplan](./floorplan-pages.html)|main UI|main UI|JSON DB|
|[Chart](./chart-pages.html)|main UI|main UI|JSON DB|
|[Tabbed](./tabbed-pages.html)|main UI|main UI|JSON DB|
## Designing Pages
You can see the list of your Pages in the administration area of the main UI under **Settings > Pages**, and from there, create new ones, as well as modify or remove existing ones.
::: warning ATTENTION
Sitemaps that you created in configuration files (`sitemaps/*.sitemap` files) are not displayed in this list.
:::
Every type of Page has its own designer but all of them with feature a **Design** tab and a **Code** tab.
In the Design tab, you have a view of the Page that easily allows you to add [Widgets](./building-pages.html) in various parts. Every designer also has a _"general settings"_ table that will allow you to specify the identifier, the label, as well as some common settings.
You will often find black buttons denoting that the component beside or beneath it can be customized. Some will open menus, that allow to open the configuration sheet for this particular component, reorder them, copy or paste them, remove them, or bring up the part of the YAML structure describing it and its descendents.
![Widget Context Menu](./images/widget_context_menu.png)
In the Code tab, you will be able to alter the component structure of the page, either with the sitemap syntax, or with YAML. In case of YAML, you can trigger autocompletion in many places of the YAML code:
- at the root or component level, hit <kbd>Ctrl+Space</kbd> to start a `config` section, a `slots` section, or a `slots` section with a `default` slot;
- at the `config` level, hit <kbd>Ctrl+Space</kbd> before the property name to display a list of properties and add one of them;
- at the start of a property's value in `config`, hit <kbd>Ctrl+Space</kbd> to display a list of options if the property has some (including items).
Some of the designers will also have a Run mode that you can activate with the switch on the bottom toolbar if present, or the <kbd>Ctrl+R</kbd> keyboard shortcut. It will allow you to preview the page as it would be rendered (some actions will still not work in Run mode).
## Organizing & Displaying Pages
Whereas in sitemaps, the entirety of the hierarchy is constrained within the sitemap definition, other types of pages are standalone, but can link to each other.
You can indeed navigate from one page to the next, either with standard full-screen replacement, or in a modal window: you do that by configuring appropriate actions on some of the source page widgets, referencing the next.
For instance, clicking on a marker on a Floor plan page can open a popup, displaying a Tabbed page itself containing a Chart page, a Layout page and a Map page.
By carefully designing the navigation & interaction between pages, you can make up a coherent and complex user interface system.
You have two entry points to this system at your disposal:
1. the Overview page;
1. Pages that you promote to the main UI's Sidebar.
### The Overview Page
A Layout Page named **Overview** (id: `overview`) is automatically created when you start.
The contents of this page will be shown on the Overview tab of the home page (see above): this page will be displayed when you open the main UI with the default URL.
As a result, it's arguably the most important of them all, because that's what yourself, your household members and your eventual guests will see first, possibly on their narrow mobile screens.
You should therefore make good use of this page and carefully design it to be as straightforward as possible, and restrict it to the most important controls only instead of cramming it with information that might not be always useful or relevant; common examples include scenes for the entire home, buttons to indicate presence, various alerts, or dynamically displayed information based on context.
You can also use it as the starting point of a more elaborate menu system made of other Pages.
You will likely notice, the more you use the user interface, that when you use it at all, you always come back to the same controls: that's because you (hopefully) made comprehensive automation rules to make sure all you need to get to the state that you want is triggering those rules - and this can be done with a mere button. Those are the critical controls that you should focus on when designing your home page.
Of course, you will also probably need to dive into details from time to time, but everything doesn't have to fit on this overview page, so you can also create more of them that will be displayed upon clicking on a button.
### The Sidebar
Another entry point to start navigating your Pages is to put some of them on the main UI's Sidebar: they will appear on the left side, or in the left drawer on smaller screens, just below the openHAB logo.
To put a page on the Sidebar, open the _Sidebar & Visibility_ option in a Page's general settings, and enable the **Show on Sidebar** toggle.
**Sidebar order** allows to reorder the sidebar menu, choose an integer for each page on the sidebar, the lower values will make the page higher in the menu.
## Additional Properties
You can put additional properties on a page's root component config which will influence its display.
### Visibility Restriction
The `visibleTo` property allows you to control whether the page will be viewable based on the current user's role.
The built-in roles `user` and `administrator` will be configurable in the Design tab, but you can also use YAML, in which case an array of `role:(role)` and/or `user:(userid)` strings is to be specified.
::: warning
Do not be fooled into assuming the “visible only to” feature gives you any security, its only a way to restrict the visibility; it can be enough for non tech-savvy users but there are many ways to circumvent this restriction and talk to your items anyways.
:::
### Additional Styling
The `pageStyle` and `modalStyle` properties can be used on a Page component itself to set additional CSS properties to the parent responsible for displaying the page, normally not accessible.
The styling will be applied to the `f7-page` component (in the former case, for pages displayed full screen, in the latter case, for pages displayed in a modal like a popup window).
These properties are useful for instance to configure the background, or alter some CSS properties for the entire page.

133
ui/layout-pages.md Normal file
View File

@ -0,0 +1,133 @@
---
title: Layout Pages
---
# Layout Pages
Layout Pages are used in the main web user interface to display widgets in an organized manner.
You can choose among several layouts, based on whether you want to control the layout completely, or let the container decide where to place the widgets.
![Layout Page Example](./images/layout_example.png)
## Anatomy of a Layout Page
A layout page can host one or multiple **blocks**, optionally followed by a **masonry** layout.
In every block there could be an arbitrary set of **rows** or **cells** containers.
In a cell container, you may add widgets from the standard cell widget library (or personal widgets, provided they're based on a `oh-cell` widget or derivative).
In a row, you may add **columns** which will spread across the row, possibly wrapping their contents to another row (but still within the same `oh-grid-row`).
Each column can host one widget from the standard standalone widget library, or a personal one.
The masonry container will decide how many columns it has based on the screen width, and will try to arrange the widgets automatically to form a compact layout.
## Designing Responsive Layout Pages
When you're designing a layout page, it's important to remember how this page will be used.
Sometimes, it will be on a phone, and other times on a bigger screen.
With that in mind, it is advisable to build the page for the narrow screens first, and then make sure it expands gracefully to the wider ones, instead of thinking the other way around. If you plan to share the UI you built, you can expect them to access it with mobile devices rather than desktop computers.
For cells and masonry, you don't have to worry about it, it will be handled for you. However, when you choose to keep control of the layout by making use of rows and columns, you need to take extra care about the responsive breakpoints.
These are controlled using the parameters on the column (`oh-grid-col`) components - you can configure them in the Design tab with the *Column Options* menu entries, or in YAML with the Code tab or a "Edit YAML" options on a parent component.
![Column Options](./images/responsive1.png)
Using code, you can quickly duplicate the breakpoints for similar columns.
The breakpoints work like this: the `width` property of the column is the default width that will be applied for the smallest screen, then `xsmall`, `small`, `medium`, `large`, `xlarge` width will apply on wider screens appropriately:
| Property | Minimum screen width | Examples of devices |
|----------|----------------------|---------------------|
| `width` | No minimum, default | All devices including phones |
| `xsmall` | >= 480px | Smartphones in landscape mode |
| `small` | >= 568px | Smaller tablets (Nexus 7...) in portrait mode |
| `medium` | >= 768px | Most tablets in portrait mode |
| `large` | >= 1024px | Smaller/regular tablets (iPad, iPad Mini...) in landscape mode* |
| `xlarge` | >= 1200px | High-end tablets (iPad Pro...), desktops |
<footnote><small>* Note that the sidebar will potentially be displayed and has a width of 260px</small></footnote>
If you don't specify any width or breakpoints, the column will spread evenly on the row, without wrapping. This is fine for a couple of columns and simple widgets only, since on a small smartphone screen, you will rapidly get out of room.
That's why you may find yourself wanting to let a column be 100% by default, so that it occupies the entire screen, and then reduce the width for `medium` or `large` breakpoints.
For example, given this set of rows & cols:
```yaml
config:
label: Overview
blocks:
- component: oh-block
config: {}
slots:
default:
- component: oh-grid-row
config: {}
slots:
default:
- component: oh-grid-col
config:
width: "100"
small: "50"
medium: "33"
slots:
default: []
- component: oh-grid-col
config:
width: "100"
small: "50"
medium: "33"
slots:
default: []
- component: oh-grid-col
config:
width: "100"
medium: "33"
slots:
default: []
```
This is how the layout will adapt depending on the width of the screen:
![Responsive Layout](./images/responsive2.gif)
## How to Build a Layout Page
### Defining the Layout
When you create a new Layout Page, you'll notice the 2 buttons **Add Block** and **Add Masonry**.
Clicking either will add the respective container to the page.
If you have multiple blocks, you can use the black context button (or the Code view) to reorder them with the Move Up/Move Down menu options.
You can also copy it and paste it as another block after they've been designed, if you wish to have multuple similar blocks.
You can also give a title to the block which will be displayed above it.
Blocks are also good candidates to use the conditional visibility features on, with the `visible` and `visibleTo` properties.
You can restrict what's displayed on the page based on an expression, or who is currently viewing the page.
In Design mode, _you will not be able to see the effect of these properties_, notably `visible`, but in Run mode they will be taken into account.
Under blocks, as explained above, you can have a mix of cells or rows. The 2 buttons **Add Row** and **Add Cells** will let you add more of them.
They will be added at the end of the block, but as for the blocks themselves, you can reorder them, or duplicate them, using the context menus or the YAML.
In Design mode, rows will feature an additional step before you can actually add widgets: adding columns: the **Add Column** serves this purpose.
### Adding Widgets
Big gray placeholders with a "+" sign will appear where you can add Widgets.
Depending on the type of containers, different widgets from the Standard library will be offered in the menu, as well as widgets from your personal library.
You will also get an additional option: **Add from Model...**. This option will display your semantic model, and let you pick one or several items, then add them in the container. The Widget that will be added will be the _default widget_ for the item for that type of container which can be controlled with metadata:
- for columns or masonry, the _default standalone widget_;
- for items inside list cards, the _default list item widget_;
- for cell containers, the _default cell widget_.
![Add from Model](./images/add_from_model.png)
::: tip REMARK
The widget that will be put on the page is a _copy_ of the current widget as defined in metadata at the time of the addition; if you change this definition for an item, widgets that were already put on a page with the **Add from Model...** feature will **NOT** be updated.
:::

26
ui/map-pages.md Normal file
View File

@ -0,0 +1,26 @@
---
title: Map Pages
---
# Map Pages
Map Pages can display either fixed markers or markers representating items of type Location, on a map.
![Map Example](./images/map_example.png)
## Anatomy of a Map Page
Map pages have some configuration properties that you mostly can define in the Design mode.
You can also add two types of markers in the Markers area.
- A Marker is an icon that will represent a position; you can define an icon, a label, and either a fixed position or a Location item. You can also define an action that will be performed with the marker is clicked.
- A Circle Marker is a marker that will be represented as a circle on the map; it's useful for representing ranges. Instead of definining an icon, you can define a fixed radius in meters, or use the state of an item to control this radius. You can alter the look of the circle marker in the `markerConfig` YAML-only config property; it will be forwarded to the [LCircle](https://vue2-leaflet.netlify.app/components/LCircle.html#demo) component as props.
## Building a Map Page
In the Design view, configure the properties below Page Configuration.
Some of them, like the background tiles or overlay providers, will indicate that some additional properties may need to be defined in YAML, for instance to set an OpenWeatherMap API key for the associated overlays to work.
To add markers, under Markers, click either **Add marker** or **Add circle marker** as necessary. Then click on the newly added entry to configure the marker. using the black context menu, you can reorder or remove existing markers.
Use the Run mode to preview the page.

18
ui/tabbed-pages.md Normal file
View File

@ -0,0 +1,18 @@
---
title: Tabbed Pages
---
# Tabbed Pages
Tabbed Pages are composite Pages which are able to display other Pages in tabs.
![Tabbed Example](./images/tabbed_example.png)
## Anatomy of a Tabbed Page
Tabbed pages are very simple: you can only add `oh-tabs` components which will have a label, icon, and a reference to another Page.
The tabs will be displayed in the order they're defined.
## Building a Tabbed Page
In the Design view, under Tabs, click **Add tab** to add another tab. Then click on the newly added entry to configure the tab. using the black context menu, you can reorder or remove existing tabs.