Getting started UI Pages (#1503)

* Added intro to Pages

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Added Overview tabs tutorial page

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Added item  widget customization page

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Added custom widgets page

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Corrected page formatter

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Removed some : to keep the parser from misinterpreting it as YAML

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Changes to make markdownlint happy

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Corrected minor typos, fixed table

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Fixing typos.

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Typos and minor edits, fixed linting error

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Typos and minor edits, added section on column widths

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Added new pages to sidebar

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Updating the toc on the index page

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Fixed title

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* sneaking in one last change, making the page titles more consistent

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Updates to address review of first two pages.

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Addressing comments.

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Retyped line with hidden characters.

Signed-off-by: Rich Koshak <rlkoshak@gmail.com>

* Fix typo

Signed-off-by: Jerome Luckenbach <github@luckenba.ch>

Co-authored-by: Jerome Luckenbach <github@luckenba.ch>
pull/1515/head
Richard Koshak 2021-03-19 02:28:47 -06:00 committed by GitHub
parent 8121ebae5a
commit f8225251a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 883 additions and 8 deletions

View File

@ -17,6 +17,10 @@ module.exports = [
'tutorial/things_advanced',
'tutorial/model',
'tutorial/persistence',
'tutorial/pages_intro',
'tutorial/auto_overview',
'tutorial/item_widgets',
'tutorial/custom_widgets',
/*'tutorial/pages_intro',
'tutorial/pages_widgets',
'tutorial/pages_types',

View File

@ -0,0 +1,204 @@
---
layout: documentation
title: Pages - Overview Page
---
# Automatically Generated Overview Tabs
MainUI will automatically generate an Overview page (id:overview).
This Overview page has four tabs: Overview, Locations, Equipment, and Properties.
{::options toc_levels="2..4"/}
- TOC
{:toc}
## Overview Page
This is a page that is automatically create as soon as openHAB is installed.
It cannot be deleted but it can be customized.
### Overview Tab
When first starting with openHAB this page will initially be blank with a link to documentation and this tutorial.
This is the very first page your users will see when first accessing openHAB.
It is a great place to put the most commonly accessed controls and information.
However, this tab is completely custom built so how to do that is covered on the next pages of this tutorial.
### Location Tab
The model is really starting to pay off now!
All of the Locations from your semantic model that have Equipment or Point Items directly in them will have their own card presented.
For some types of Properties, a badge with a summary of that property at that location is shown on the card itself.
Clicking on the card will bring up a list showing all the Equipment and Properties at that location.
Equipment is represented as a gray bar with the name of the Equipment each Point/Property is shown with its default list widget.
![Locations tab](images/locations_tab.png)
A Location's card is separated into two tabs, Equipment and Properties.
The Properties tab shows those Point/Property Items from the model that are direct members of this Location and not a part of an Equipment.
![living room card](images/livingroom_card_equip.png)
The badges shown on the card summarize all the Properties in that card and present that summary as a single badge.
When there is nothing to present the badge is not shown.
For example, if no lights are on, the lights badge will not be shown.
When one light is on the light badge will be shown.
When two or more lights are on, the light badge will be shown with a number indicating how many lights are on.
For other types of sensors like temperature, the average of all the Items tagged with a Temperature Property tag will be shown.
### Equipment Tab
Each equipment type is represented by a card showing a list similar to that shown on the Locations card.
Each instance of the equipment is shown with a gray bar and the equipment name and each Point/Property is shown in a list under that title.
![Equipment tab](images/equipment_tab.png)
![Equipment card](images/equipment_card.png)
Also notice how an Equipment can be an abstract concept where necessary.
In this case the sun is modeled as an Equipment.
### Properties Tab
Each Point Item that has a Property tag is represneted by a card showing each instance of that Property in the list.
Unlike the other tabs, the gray bars here represent the Point tags and each Item with that Point is listed under that.
What this means is for something like the Temperature Property, one will have a set of all the temperature Measurements grouped together and then all the temperature Setpoints grouped together all on the same Temperature card.
![Properties tab](images/properties_tab.png)
![Temperature card](images/properties_card.png)
On the bottom of each card in the properties tab there is an "Analyze All" button.
Clicking on that will bring up a chart showing the history of all the Items on that card over time.
You can hide Items from the chart if it's to busy and change many other chart settings in the control tab under the chart.
![Properties chart](images/properties_chart.png)
Now persistence is starting to pay off!
If you've customized the chart and want to return to the same chart again, you can save it and a new [Chart Page]({{base}}/ui/chart-pages.html) will be created showing those Items with those settings.
## Customization / Page Configuration
MainUI does a pretty good job of guessing a decent default method to present the information to you.
But what's the fun in just accepting the default?
Luckily there are a lot of opportunities for customization.
You've already seen some customizations to the Locations tab above.
### Page Layout
On any given tab the order of the cards can be adjusted and spacers inserted to group like cards together.
For example, in the Locations tab screen shot above, all the rooms on a floor are grouped together and a spacer added to indicate which floor is represented.
To adjust those settings, while logged in as an administration user, click on the pencil icon in the upper right corner of the Locations tab.
This will open the customization page.
![Pencil icon](images/pencil_icon.png)
![Overview edit page](images/overview_edit_page.png)
There are a few global settings for the overview pages itself and then each of the three auto generated tabs have their own settings.
Field | Purpose
-|-
Display model cards to | Controls what type of user can see the cards. If Administors is checked only an administrator user can see the cards tabs.
Allow chat input box to | If HABot is installed, this controls what sort of user can access the HABot chat box.
Hidden Model Tabs | Allows the Locations, Equipment, and/or Properties tabs to be hiddin to all users in case they are not used.
Below these settings one can select one of the three tabs to customize.
This will list all the possible cards that can be shown on that tab based on your model.
MainUI will only show those cards that have something in them even if that card is checked to be shown.
Unchecking a card will remove it from being shown on that tab even if it does have entries in it.
Next to each card entry there is a black and white icon that will open that card's customization form when clicked.
#### Reorder
To change the order of cards, click the "Reorder" button (upper right corner of the list of cards) and drag and drop the card you want to move via the handle (=) to the very right of that card.
#### Separators
To visually group cards on the Page insert a separator. In the screen shot above you can see a separator for Ground Floor has been inserted.
To insert a separator, click on the menu icon of that card you want to be the first one below the separator and select "Add Separator Before."
![add separator before](images/add_separator.png)
Give the separator a name and on the page you will no see a section heading with the entered name and all the Items below the separator grouped under that section heading.
![separators](images/separators.png)
Tip 1 - Make sure to save before clicking "Back" or otherwise leaving the page.
You will have to reload the page to pick up the changes.
Tip 2 - Open two separate tabs in your browser where you edit and view your page.
Alternatively, hit CTRL-R to force a reload and show the changes.
#### Card Customization
There are a number of customization options for a card through the customization menu.
More advanced customizations can be added by editing the card's YAML directly.
To customize a given card clikc on the menu icon and select "Configure Card".
This will open a form with customication options.
![customize location card form](images/Customize_location_card_form.png)
##### Basic Settings
Instead of using the Item's Label and parent Group as the Title and Subtitle of the card, these can be overridden and manually set.
[Expressions]({{base}}/ui/building-pages.html#dynamically-configuring-components-with-expressions) can be used to have the Title and Subtitle change based on the states of Items or other conditions.
By default a background color is chosen based on the semantic tag.
This default can be overridden here.
##### Background Image
This feature may require a bit more work.
If you find a picture that allows cross linking to all you need to do is put in the URL of that picture in this field and MainUI will load it and make it used as the background for the card.
However, text and icons will be displayed on top of the image so one might need to modify the original image to work.
Or one may have their own images they want to use instead of something downloaded from the internet.
For example, one might use high contrast images (e.g. architectural drawings and water color paintings) as the background images.
However, those images tend to be very light with very high contrast which makes both white and black text unreadable in many cases.
There are two approaches you can use to deal with this.
You can edit the image to lower the contrast and/or brightness or crop the image to a less busy portion.
Alternatively, you can open the YAML for a given card and adjust the brightness down in the settings.
Click the config icon and choose "Edit YAML".
Here I show adjusting the image brightness down to 60%.
```yaml
component: oh-location-card
config:
backgroundImage: /static/garage.jpg
backgroundImageStyle:
filter: brightness(60%)
invertText: false
```
Once you have your custom images, place them in $OH_CONF/html.
Once they are there, you can use the relative path `/static/image.name` as the URL to the image.
For example, I placed the file `garage.jpg` in `/etc/openhab/html` and reference it as you see in the YAML above.
This is how to use a custom image as the background of a card.
You can see some stock images used as the backgrounds for the cards on the Locations tab in the demo and screen shots above.
Note, even though it is theoretically possible and tempting to just link to an absolute URL on the internet, as it doesn't require to save the image file to openhab's server, doing so is highly discouraged for security, link dependency, image sizing and other reasons.
##### Badges
Badges are only available on the Location cards.
If one wants to not show any badges at all toggle "Disable badges".
If one wants to only suppress certain badges, select those that you want to show under "Enable Badges".
##### Advanced Configuration
For an individual card or to edit the Page itself one can switch to show the YAML code.
Many actions like reordering the cards and inserting separators will be faster to do through the code.
Any advanced customization of the cards themselves through editing of the code directly is beyond the scope of this tutorial.
See the [UI Docs]({{base}}/ui/index.html) for a detailed reference.

View File

@ -0,0 +1,464 @@
---
layout: documentation
title: Pages - Custom Widgets
---
# Custom Default Item Widgets
As mentioned on the previous page, MainUI allows for the creation of custom widgets.
These custom widgets can be reused for multiple Items in a given openHAB setup or they can be shared with the community.
A growing number of very impressive custom widgets have been posted to the [Add-ons -> UI on the forum](https://community.openhab.org/c/add-ons/uis/30).
This page is going to provide only a couple of examples of custom widgets with an emphasis on the over all approach to developing your own.
For a comprehensive reference on creating widgets, please see the [Building Pages]({{base}}/ui/building-pages.html) guide in the docs.
{::options toc_levels="2..4"/}
- TOC
{:toc}
## Where to Create Custom Widgets
In MainUI under Developer Tools there is a "Widgets" option.
Opening this will present a page with a list of all the custom widgets.
Clicking the + icon will open the editor which is a window split in half with a text entry area on the left and a preview on the right.
![custom widget editor](images/custom_widget_editor.png)
Note that when creating a custom list widget, the preview page will not render the widget in progress.
One will have to apply the widget to an Item and refresh a page after saving the changes for that type of Item.
## Building Custom Widgets
As you are learning how widgets work and all the options available, it might be easier to create the widget using the form presented when adding the Item metadata and then copying the YAML from the code tab to the Custom Widget editor.
When doing this, make sure to fill out *all* the fields because when using the defaults, no value is added to the YAML in the code tab.
So, for example, be sure to enter in the Item field.
Here is a filled out form customizing a list Item widget for a light.
![light list item widget form](images/light_list_widget_form.png)
Clicking on the code tab shows the following YAML.
```yaml
value: oh-toggle-item
config:
icon: f7:lightbulb
iconColor: '=(items.AllLights.state == "ON") ? "yellow" : "gray"'
title: All Lights
color: '=(items.AllLights.state == "ON") ? "yellow" : "gray"'
item: AllLights
```
Now go to Widgets under Developer Tools and create a new custom widget.
The YAML will be prepopulated with a skeleton configuration.
```yaml
uid: widget_5c7a60b74f
props:
parameterGroups: []
parameters:
- name: prop1
label: Prop 1
type: TEXT
description: A text prop
- name: item
label: Item
type: TEXT
context: item
description: An item to control
tags: []
component: f7-card
config:
title: '=(props.item) ? "State of " + props.item : "Set props to test!"'
footer: =props.prop1
content: =items[props.item].displayState || items[props.item].state
```
Give your new widget a meaningful name and tags.
Each widget needs to have a unique name and that name is how it will appear in the list when you apply it to an Item.
Now replace the value of "component" in the custom widget with the "value" from the YAML you generated above.
Then replace everything under "config" in the custom widget with everything under "config" from the YAML you generated above.
```yaml
uid: test_light_list
props:
parameterGroups: []
parameters:
- name: prop1
label: Prop 1
type: TEXT
description: A text prop
- name: item
label: Item
type: TEXT
context: item
description: An item to control
tags:
- lights
- list
component: oh-toggle-item
config:
icon: f7:lightbulb
iconColor: '=(items.AllLights.state == "ON") ? "yellow" : "gray"'
title: All Lights
color: '=(items.AllLights.state == "ON") ? "yellow" : "gray"'
item: AllLights
```
Now we want to create some properties so that the widget can be customized for the any light Item.
We can leave the Item property alone as that's what we want so we will change prop1 to be used for the title.
Then we will change the config to use the properties instead of the hard coded values.
```yaml
uid: test_light_list
props:
parameterGroups: []
parameters:
- name: title
label: Widget Title
type: TEXT
description: Used as the label for the widget.
- name: item
label: Item
type: TEXT
context: item
description: The item to control
tags:
- lights
- list
component: oh-toggle-item
config:
icon: f7:lightbulb
iconColor: '=(items[props.item].state == "ON") ? "yellow" : "gray"'
title: =props.title
color: '=(items[props.item].state == "ON") ? "yellow" : "gray"'
item: props.item
```
Save the widget and return to one of the Items that should use this widget.
Select "test_light_list" as the widget type and you will be presented with a form to enter the title and select the Item.
![applying custom list widget](images/applying_custom_list_widget.png)
When ever the custom widget is changed, every Item that uses the custom widget will be updated with the change.
This is a powerful tool to create and maintain the look and feel of your UIs.
## A More Complex List Item Widget
Here is an example widget that combines two Items into one widget.
In this case it's a widget that represents a garage door and combines the sensor that indicates the opened/closed status of the door and the actuator to trigger the garage door opener.
![garage list widget](images/garage_list_widget.png)
```yaml
uid: garagedoor_list
tags:
- list
- garagedoor
props:
parameters:
- description: Door name
label: Name
name: name
required: false
type: TEXT
- context: item
description: Control Item
label: Control Item
name: control_item
required: false
type: TEXT
- context: item
description: Sensor Item
label: Sensor Item
name: sensor_item
required: false
type: TEXT
parameterGroups: []
timestamp: Feb 5, 2021, 2:01:31 PM
component: oh-list-item
config:
icon: '=(items[props.sensor_item].state == "CLOSED") ? "f7:house" : "f7:house_fill"'
iconColor: '=(items[props.sensor_item].state == "CLOSED") ? "green" : "red"'
title: =props.name
action: command
actionItem: =props.control_item
actionCommand: ON
badgeColor: '=(items[props.sensor_item].state == "CLOSED") ? "green" : "red"'
badge: '=(items[props.sensor_item].state == "CLOSED") ? "CLOSED" : "OPEN"'
```
Notice how the sensor_item prop is used to control the icon, badge and color and the control_item is used as the Item that gets commanded by the Action.
## Custom Stand Alone Widgets
Up to this point the tutorial has focused on list item widgets because as someone who is just getting started, making minor tweaks to what is automatically generated will likely be the primary focus.
However, there is that Overview tab that needs to be manually populated too.
This page will be populated with stand alone widgets, or card widgets.
Often, one will want to have one single stand alone widget to represent a single Equipment, for example a thermostat or a Chomecast.
These will be a single card that provides the display and interaction with many Items.
If one has more than one Equipment that will use the same widget, or the widget is complex, create a custom widget for these.
Once created, apply the custom widget to the Equipment Group Item in the model.
Then on your Overview tab, or any other page, you can select "Add from Model", select the Equipment and it will drop the unified widget onto the page.
## Example Stand Alone Widget
This is a widget to represent a Chromecast.
![Chromecast widget](images/chromecast_widget.png)
```yaml
uid: chromecast_widget
tags:
- card
props:
parameters:
- description: How all the Items associated with this chromecast starts
label: Item prefix
name: prefix
required: false
type: TEXT
- description: Title for the widget
label: Static Title
name: title
required: false
parameterGroups: []
timestamp: Feb 2, 2021, 12:15:54 PM
component: f7-card
config:
title: =props.title
slots:
default:
- component: f7-row
slots:
default:
- component: oh-image
config:
item: =props.prefix+"_Image"
style:
width: 100%
height: auto
- component: f7-row
config:
class:
- justify-content-left
slots:
default:
- component: f7-col
slots:
default:
- component: Label
config:
class:
- text-align-center
text: =items[props.prefix+"_MediaArtist"].state
- component: f7-col
slots:
default:
- component: Label
config:
class:
- text-align-center
text: =items[props.prefix+"_MediaTitle"].state
- component: f7-row
config:
class:
- padding-top
- padding-bottom
slots:
default:
- component: f7-col
slots:
default:
- component: oh-player-controls
config:
item: =props.prefix+"_MediaControl"
- component: f7-col
slots:
default:
- component: oh-slider
config:
item: =props.prefix+"_Volume"
min: 0
max: 100
step: 10
unit: "%"
label: true
- component: oh-button
config:
text: Stop
iconF7: stop
fill: true
color: red
action: command
actionCommand: ON
actionFeedback: Media Stopped
actionItem: =props.prefix+"_Stop"
class:
- margin-top
- component: f7-row
config:
class:
- justify-content-center
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_App"].state
```
A full explanation of the widget is outside the scope of this tutorial but there are a few take aways.
As with the list widget, it might be easier to create the widget on the Page editor first and then copy that to the custom widget as described above.
First notice that not all the components used start with "oh".
When building a complicated custom widget, one has more flexibility when using the base "f7" widgets instead.
Notice how the only property related to Items is a prefix. If one is consistent in their Item naming, one can define a prefix and the widget can build the Item names for each relevant Item using the prefix.
This can greatly simplify the configuration of a widget. In this case the widget uses seven different Items that can all be obtained from that one property.
As you create a widget that uses properties you will notice that the preview does not get rendered correctly.
![Chromecast widget no props](images/chromecast_widget_noprops.png)
At the bottom of the widget editor there is a "Set Props" option, which can also be accessed by typing CTRL-p.
This will bring up a form where the props can be set for the preview.
![Chromecast widget props set](images/chromecast_props_set.png)
Once created, apply the custom widget to the Equipment Group Item in the model by selecting it as the default stand alone widget.
## Dynamic Widgets
It is also possible to create widgets that are dynamically populated from the model.
This is particularly useful to present a functional widget such as one widget to control all the lights in the house.
For this the [oh-repeater]({{base}}/ui/components/oh-repeater.html) component will be very useful.
This component allows one to set up a loop to iterate over a bunch of things such as all the Items with a given semantic properties tag and create a widget element for each one.
For example, here is a widget that shows all the Items with a Switch and Light tag, filtering out those that have "Christmas" in the name unless the TisTheSeason Switch is ON.
![all lights widget](images/all_lights_widget.png)
```yaml
uid: all_lights
tags:
- card
- lights
props:
parameters:
- description: A text prop
label: Prop 1
name: prop1
required: false
type: TEXT
- context: item
description: An item to control
label: Item
name: item
required: false
type: TEXT
parameterGroups: []
timestamp: Feb 11, 2021, 3:03:59 PM
component: f7-card
config:
title: Lights
slots:
default:
- component: oh-list
slots:
default:
- component: oh-repeater
config:
fragement: true
for: item
sourceType: itemsWithTags
itemTags: Switch,Light
filter: loop.item.label.includes("Christmas") == false || items.TisTheSeason.state == "ON"
slots:
default:
- component: oh-toggle-item
config:
icon: f7:lightbulb
iconColor: '=(loop.item.state == "ON") ? "yellow" : "gray"'
color: '=(loop.item.state == "ON") ? "yellow" : "gray"'
title: =loop.item.label
item: =loop.item.name
```
There are a number of options for looping.
Please see the docs for more details.
## Adding Widgets to Pages
Now that the widgets are created it's time to put them on a Page.
We will focus on the Overview tab of the Overview page.
To edit any Page go to Settings -> Pages in MainUI. There will be a grayed out entry which represents the customized Locations, Equipment, and Properties tabs and there will be an Overview entry.
That represents the Overview tab.
Clicking on that will brgin up a configuration page that allows one to configure the Overview tab with your custom widgets.
You can build the widgets here but it's more flexible to create custom widgets and add them to this page.
A full description on how to build the page is beyond the scope of this tutorial.
See the [Layout Pages docs]({{base}}/ui/layout-pages.html) for details.
You will be presented with a page similar to the following.
![blank overview](images/blank_overview.png)
Because this is the first thing your users will see when accessing openHAB, the most commonly use actuators and widgets should be on this page.
To get started, click "Add Block", then "Add Row" and finally add how ever many columns you want.
Repeat for additional rows.
For this tutorial we will have two rows and three columns.
![Overview row and columns](images/overview_row_and_columns.png)
Now we will add a custom widget to that first columnn.
In this case we will add a garage door widget that includes a camera feed and shows the status and allows triggering two garage doors.
Click on the + in that first cell and select the desired widget from the list.
This is a simple widget that doesn't use any properties so we are done.
Next we'll add the all lights widget from above.
Click on the second cell and select the desired widget from the list.
This is a dynamic widget but also doesn't have any properties so we are done with it.
Finally we will add a services status widget which shows any home automation related devices or services that are offline.
This one is also a dynamic widget without properties.
The Page currently looks as follows.
![Overview row one populates](images/overview_row1_config.png)
Now we will fill out the bottom row with some widgets from the model.
The Chromecast widget was applied to all the Chromecast Equipment Group Items as the default stand along widget.
Click on the first cell in the second row and this time select "Add from Model".
Navigate to the Equipment Item desired and "Pick" it.
Alternativly you can select the custom widget from the list and set the properties instead of adding from the model.
When you add the widget this way, the widget will look just like it does in the preview when the properties are not yet set.
To set the properties here click on the edit icon and select "Configure Widget".
You will be presented with a form to enter the values for the properties, in this case the Item prefix and title.
![Kitchen Chromecast Widget Props](images/kitchen_widget_props.png)
To preview the configuration in progress there is a toggle at the bottom of the page for "Run mode" or you can press CTRL-R.
![Overview preview](images/overview_preview.png)
Once you are happy, save the page and that will become your Overview page.
## Responsive Pages
The Page will be viewed on a variety of screen sizes from computers to tablets to phones.
To make the page adapt to the different screen widths there is a "Column Settings" option in a given column's setting icon.
![Column Settings](images/column_options.png)
This lets you define what percentage of a row a given column takes up based on the size of the screen the Page is being displayed upon.
The above configuration is set for all the columns and consequently each coard will take up the full width of the screen unless it is a very wide screen (e.g. computer screen).
## Additional Pages
You can create any number of additional pages as desired.
Layout Pages like the Overview tab on the Overview Page are not the only types of pages that can be created.
[Chart pages]({{base}}/ui/chart-pages.html), [Floorplan pages]({{base}}/ui/floorplan-pages.html), [Map pages]({{base}}/ui/map-pages.html), and [Tabbed pages]({{base}}/ui/tabbed-pages.html) are also available.

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -74,17 +74,19 @@ This tutorial presents a series of concepts and steps that build upon one anothe
[Adding Things: Advanced]({{base}}/tutorial/things_advanced.html): Manual creation of Things
[Items and the Semantic Model]({{base}}/tutorial/model.html): Creating Items and putting them into a semantic model
[Items and the Semantic Model]({{base}}/tutorial/model.html): Creating Items and Putting Them into a Semantic Model
[Persistence]({{base}}/tutorial/persistence.html): Saving and retrieving historic data
[Persistence]({{base}}/tutorial/persistence.html): Saving and Retrieving Historic Data
[Intro to Pages]({{base}}/tutorial/pages_intro.html): Visualizing and Using the Home Automation
[Overview Page]({{base}}/tutorial/auto_overview.html): Automatically Generated Overview Page
[Item Widget Customization]({{base}}/tutorial/item_widgets.html): Customize How Items Appear in Cards
[Custom Item Widgets]({{base}}/tutorial/custom_widgets.html): Creating your own widgets
<!--
[Pages: Introduction]({{base}}//tutorial/pages_intro.html): What are Pages?
[Pages: Widgets]({{base}}/tutorial/pages_widgets.html): Introduction to populating Pages
[Pages: Page Types]({{base}}/tutorial/pages_types.html): Layout, Charts, and Tabbed type Pages
[Rules: Simple]({{base}}/tutorial/rules_simple.html): Introduction to rules and a simple example
[Rules: Intermediate]({{base}}/tutorial/rules_intermediate.html): Rules that involve some scripting

View File

@ -0,0 +1,132 @@
---
layout: documentation
title: Pages - Item Widgets
---
# Custom Default Item Widgets
Just like the Overview Page and individual cards, the way individual Point Items are presented can be customized as well.
In general the steps will include navigating to the Item in the Model tree or the Items Settings, clicking on "Add Metadata", and selecting "Default List Widget" to customize how the Item appears in the automatically generated cards on the Overview Page.
One can also set the "Default Stand Alone Widget" and "Default Cell Widget" to change how an Item appears in other parts of MainUI.
{::options toc_levels="2..4"/}
- TOC
{:toc}
## Expressions
Many portions of a widget can be configured to change dynamically based on the states of Items.
This can be a powerful way to combine multiple Items into one widget (e.g. an oh-label widget showing the current state of a garage door that sends a command to a Switch Item to trigger the garage door opener when the widget is clicked).
Common things one might use an expression for is to change an icon or color based on the state of an Item, hide a widget entirely if an Item isn't in a given state, colors of the widget elements, etc.
For full details on expressions see the [Expressions docs]({{base}}/ui/building-pages.html#dynamically-configuring-components-with-expressions).
Note that when working with Units of Masurement, the state of the Item needs to be parsed into a number for comparisons.
For example -
```javascript
=(Number.parseFloat(items.MainFloor_Humidity.state) < 35) ? "red": "blue"
```
When creating anything but the simplest of expressions, the Widgets Expression Tester is a very helpful tool.
This is the third tab of the Developer Sidebar (accessible from Developer Tools or by pressing ALT-SHIFT-d).
Note that the sidebar will only appear if the browser window is wide enough.
![expression tester](images/expression_tester.png)
For complicated expressions, gradually build up the expression in this tool until it works as required and then paste it into the config for the widget.
## Visibility
Each custom defined widget has a "Visibility" and "Visible to" property.
The "Visibility" option takes a boolean `true` or `false` (without quotes) or the result of a boolean expression to determine whether or not to render the widget.
The "Visibile to" property controls which type of user can see the widget.
Take heed of the warning, this is not a security feature, but it can be used to limit what a regular user can see in the automatically generated parts of the Overview Page.
There are other ways to hide an Item from the automatiaclly generated parts of the UI page.
### Exclude the Item from the Model
There may be times where a piece of Equipment may have one or more Items that simply do not matter in the UI.
Perhaps that Item is already displayed as part of another Item's custom list widget or it presents information or a control that the human users do not need.
Instead of setting the visibility property, simply exclude the Item from the model by removing the Item's semantic tag.
If the Item isn't used anywhere else, consider removing the Item entirely.
Do not keep Items around just because you can.
### Conditional Visibility
There may be times when certain Point Items are not relevant or interesting unless it is in a certain state or some other Item is in a certain state.
For example, a smart plug may have a bunch of sensor readings indicating how much energy the device plugged in is using.
Those Items are only interesting when the plug itself is ON.
Therefore hide the sensor readings Items by using an expression to only show it when the plug Switch Item itself is ON.
Here are a set of widgets for a Chromecast.
When the Chromecast isn't doing anything (Idling Channel is ON) the widgets are hidden.
![hidden points](images/hidden_points.png)
And when the Chromecast is playing something a number of widgets become visible.
![visibile points](images/now_visible_points.png)
Note that even though the points for an equipment are hidden, the Equipment itself still appears in the card with that gray row in the list.
The screen shots above are an extreme case where there are a lot of Equipment with hidden Points.
## Configure a Custom Widget
By default MainUI will make a best guess on how to represent an Item.
If it fails to allow the interactions desired or doesn't look the way desired, a custom widget can be defined as metadata on the Item.
To change how the Item appears in the automatically generated parts of the Overview Page, set the "Default List Widget".
You can do so from the Model settings page or from the Item's settings page by clicking on "Add Metadata".
See the [UI docs]({{base}}/ui/building-pages.html) for details on how to create custom widgets.
There is some discussion on this on the next page of this tutorial as well.
There are a number of widget types to choose from for a List Widget.
See the [widget reference docs]({{base}}/ui/components/index.html) for details.
Pay particular attention to the Standard Widget Library (List Items) section.
Some customization fields are only shown when the "Show advanced" checkbox is checked.
An important note about widgets.
If one has more than one Item that should look and behave the same, create a custom widget under Developer Tools -> Widgets and reuse that for your Items.
Once a custom widget is created, it will appear in the list of widget types.
Properties can be used to customize the widget to work for each Item.
See the docs linked to above for details and the next page of the tutorial for some generic advice and approaches.
Look in the [Add-Ons - UI Category on the forum](https://community.openhab.org/c/add-ons/uis/30) for lots of examples.
## State Representation
By default the state of the Item will be displayed on the right hand side of the widget.
Sometimes the binding will provide hints on how to display the state but most of the time this default will be just the string from `MyItem.state.toString()`.
Note, the `label` field of an Item'™s definition in a .items file or the label set on the Item is *not* used by MainUI.
To customize the state of the Item the "State Description" metadata must be configured.
This metadata lets you define the format and any transformations to apply to the Item's state before it is displayed.
When this metadata is defined, it will be used by default everywhere in MainUI.
Field | What it does
-|-
Read Only | A toggle when set tells MainUI that the Item is not controllable (e.g. a Switch used to represent a sensor state) so a text/label widget will be used instead of a toggle.
Pattern | Defines the pattern used to display the state. This is where you will define the transformation and any other formatting information according to the same [syntax as used by sitemaps]({{base}}/configuration/items.html#state-presentation). Everything that can go between the `[ ]` in an Item label as described by that doc (excluding the `[ ]` themselves) can go here.
Min/Max/Step | Hints to MainUI used for slider, setpoint, and knob type widgets.
Options | Can be used with Actions (see below) to provide a mapping between the state of the Item and a command to issue.
There may be times when you want to suppress the state of the Item entirely.
In those cases, enter a space as the pattern and the Item's state will not be shown.
![state description](images/state_description.png)
The above shows the state description for a `Number:Time` Item formatted to show the value as `HH:MM:SS`.
## Actions
There will be times when you want an entry in the card to perform some action when clicked on even when it's a sensor value.
For example, one might send a command to the garage door opener Item when clicking on the garage door sensor's Item on the card (you can then hide or remove the opener's Item from the model so it doesn't show up at all, two for one).
By default the action will usually be "Analyze item(s)" which will open up a chart of the historic state of the Items (see previous chapter).
But there are many other Actions that can be performed.
Some example use cases might be to pop up a weather widget when clicking on the Item with the outside temp on a page, combining Items into one widget when the sensor and actuator are separate (e.g. garage door), etc.
See the [UI Docs for Actions]({{base}}/ui/building-pages.html#actions) for details on all the Actions that can be performed.

View File

@ -0,0 +1,69 @@
---
layout: documentation
title: Pages - Introduction
---
# Introduction to Pages
openHAB 3 introduces a new user unified user interface called MainUI.
Should you choose to, almost everything that can be configured in openHAB can be achieved through MainUI.
In addition to the administration of openHAB, MainUI can be used as the interface you present to the users of your home automation.
You can find an example of the MainUI on the [demo page](https://demo.openhab.org/#!/).
{::options toc_levels="2..4"/}
- TOC
{:toc}
## Role Based Access
MainUI presents two different views to users based on whether and as what type of user they log in as.
The two types of users are regular users and administrators.
### Regular Users
Regular users are those who have not logged in or users who have not been configured to be administrators.
These users can see all of the interactive parts of the UI (i.e. Pages) and can open other apps (icon at the upper right hand corner of the screen) but they cannot see any of the administration user interfaces nor can they access the administration functions through the REST API.
![regular user view](images/regular_user.png)
Notice that none of the administration menus are shown; only the Pages defined to interact with your home automation.
The sidebar menu can be hidden by clicking the push pin icon right above the openHAB logo.
By default, these menus can be accessed by anyone on your network whether or not they are logged in or not.
### Administration Users
These users have full access to all parts of openHAB.
The list of menu options includes Settings, Developer Tools, and the Developer Sidebar.
These are most of the parts of openHAB you have been interacting with thus far.
Way back in First Steps the first thing you did was create an administration user.
![admin user view](images/admin_user.png)
Notice the new Settings and Developer Tools menus are now accessible.
## Other User Interfaces
Every openHAB deployment is unique.
Consequently every administrator of an openHAB instance will need to create a custom interface for the users of their bespoke home automation.
openHAB 3 provides a number of options to supports this in addition MainUI Pages.
Interface | Purpose | How the UI is Defined | Notes
-|-|-|-
[Sitemaps]({{base}}/ui/sitemaps.html) | A simple declaritive way to define a simple user interface | Created using .sitemap files or through MainUI. | Used by BasicUI and the phone apps by default.
[HABPanel]({{base}}/ui/habpanel/habpanel.html) | UI designed for fixed wall mounted tablets and similar touch screen displays using a blocks interface (e.g. the Windows 10 start menu) with a lot of customization options. | Built graphically though the browser. A number of custom widgets are defined and installable.
[HABot]({{base}}/ui/habot/) | Provides a basic chatbot interaace to interact with your home automation through natural langauge. | Requires the configuration of the semantic model.
[Pages]({{base}}/ui/index.html) | Built into MainUI that allows for a rich set of options to present your home automation. | Can be built automatiaclly through the semantic model as well as cutomized.
Once installed, any non-Pages UI can be accessed in the "Other Apps" menu that pops up when clicking on the square icon in the upper right corner of the MainUI Overview page (first page you see when first accessing openHAB).
![other apps menu](images/other_apps.png)
In addition, HABot will add a text box to the top of your Pages where one can start a conversation with openhab.
![HABot text entry](images/habot_text.png)
The rest of this tutorial will focus on Pages.