openHAB 3.0 my getting started notes: Model and Pages

Tags: #<Tag:0x00007faf81258d60>

Edit: I’ve started some more formal tutorials. You can find the first at OH 3 Examples: How to boot strap the state of an Item

Model

I decided to experiment with the model page for a bit. I don’t have much to model yet, just a bunch of Network Binding Things/Items but I was able to get started at least. I fully modeled my locations (I’ve two locations represented in openHAB) with an indoor and outdoor. Indoor is split by floor and each floor is divided by rooms. Then I put all my Items into the appropriate room.

It’s really nice to be able to add the Groups for Locations and Equipment from the Model. But I wish I could add already existing Items and Groups to the model. To do that you have to go to the Items menu, find the Item and edit it to add the Semantic tags. I’ve already filed an issue on this.

Building the Items is nice as it automatically populates the pages. But this shows how it’s more important to edit the defaults for the Items so they all get represented consistently and attractively. The Location tab though did not get populated. Not sure about that. I think I read that tab requires more configuration.

Equipment

Properties

The ways that these appear on the pages is defined by the default card and list on the Item.

So let’s change how the Item appears in the list widgets in the two pages above. Open the “Default List Item Widget”. I want to use an icon that changes color with the state, use a badge, and have ON read as “ONLINE” and off read as “OFFLINE”. So I open the entry and choose a “Label List Item” from the list of options.

I was able to get pretty close to what I wanted but I had a hard time figuring out how to suppress the Item’s state.

I clicked on “Show advanced” and defined the Title, Icon as oh:network and turned on “Icon depends on state”. That handles the wifi signal icon coloring on the left.

Then I opened the code and added a badge and badgeColor.

value: oh-label-item
config:
  badgeColor: '=(items.vMBR_Shelly_Status.state === "ON") ? "green" : "red"'
  icon: oh:network
  badge: '=(items.vMBR_Shelly_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
  iconUseState: true
  title: Master Bedroom Shelly 1 Status

I then experimented with all sorts of options for the “Pattern” under stateDescription trying to suppress the Item’s state to no avail. What finally ended up working was to set the “Pattern” to " " which I did through code.

Equipment

Properties

NOTE: I learned about how to set a badge with help from Yannick and Rainer on the documentation thread.

So, if one builds a reasonable model and configures the default widgets for each Item in the model, a custom UI may not even need to be created! Very cool!

Custom Panels

So I’ve got a ton of status Items I’d like to have a widget that collapses the statuses so at the top level I see the over all status (ON if all ON else OFF type Group). Below that I see all the home automation related devices, also aggregating the status of the services they run. Then under those I see the status of all the services. The statuses will be populated by the Network binding and MQTT LWTs.

This took a bit of trial and error and a whole lot of help from Yannick and Rainer but I managed to get it to work.

I created an oh-list-card and then opened the code so I could edit the widget manually.

This sort of collapsing list is called an accordion list. So I had to create the hierarchy of oh-list-card, oh-list, and oh-list-item entries. The hierarchy is like this:

oh-list-card
    oh-list-item
        oh-list
            of-list-item
                oh-list
                    oh-list-item

This will get you to the third level.

The widget looks like:

The full YAML (which is way overkill but here it is anyway):

component: oh-list-card
config:
  accordionList: true
  title: All Services Status
  footer: Online status of home automation related services
slots:
  default:
    - component: oh-list-item
      config:
        title: All Services
        subtitle: When OFF one or more services are offline
        badge: '=(items.ServiceStatuses.state === "ON") ? "ONLINE" : "OFFLINE"'
        badgeColor: '=(items.ServiceStatuses.state === "ON") ? "green" : "red"'
      slots:
        accordion:
          - component: oh-list
            config:
              accordionList: true
              class:
                - margin-left
            slots:
              default:
                - component: oh-list-item
                  config:
                    title: argus
                    subtitle: Home automation server
                    badge: '=(items.vArgus_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vArgus_Status.state === "ON") ? "green" : "red"'
                  slots:
                    accordion:
                      - component: oh-list
                        config:
                          accordionList: true
                          class:
                            - margin-left
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: Grafana
                                badge: '=(items.vGrafana_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vGrafana_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Grafana Image Renderer
                                badge: '=(items.vGrafana_IR_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vGrafana_IR_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: InfluxDB
                                badge: '=(items.vInfluxdb_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vInfluxdb_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Mosquitto
                                badge: '=(items.vMosquitto_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vMosquitto_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Portainer Agent
                                badge: '=(items.vArgus_Portainer_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vArgus_Portainer_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: cerberos
                    subtitle: Garage sensors and controller
                    badge: '=(items.vCerberos_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vCerberos_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: fafnir
                    subtitle: NAS Server
                    badge: '=(items.vFafnir_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vFafnir_Status.state === "ON") ? "green" : "red"'
                  slots:
                    accordion:
                      - component: oh-list
                        config:
                          accordionList: true
                          class:
                            - margin-left
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: OMV Service
                                badge: '=(items.vOMV_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vOMV_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: OMV NFS
                                badge: '=(items.vOMV_NFS_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vOMV_NFS_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: OMV Timemachine
                                badge: '=(items.vOMV_AFP_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vOMV_AFP_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: huginn
                    subtitle: Virtual Desktop
                    badge: '=(items.vHuginn_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vHuginn_Status.state === "ON") ? "green" : "red"'
                  slots:
                    accordion:
                      - component: oh-list
                        config:
                          accordionList: true
                          class:
                            - margin-left
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: Portainer Server
                                badge: '=(items.vHuginn_Portainer_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vHuginn_Portainer_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: hydra
                    subtitle: Doors and windows sensors
                    badge: '=(items.vHydra_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vHydra_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: manticore
                    subtitle: NUT and BT bridge
                    badge: '=(items.vManticore_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vManticore_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: medusa
                    subtitle: Media services
                    badge: '=(items.vMedusa_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vMedusa_Status.state === "ON") ? "green" : "red"'
                  slots:
                    accordion:
                      - component: oh-list
                        config:
                          accordionList: true
                          class:
                            - margin-left
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: Calibre
                                badge: '=(items.vCalibre_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vCalibre_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Elasticsearch
                                badge: '=(items.vElasticsearch_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vElasticsearch_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: GitLab
                                badge: '=(items.vGit_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vGit_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Guacamole
                                badge: '=(items.vGuacamole_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vGuacamole_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: NextCloud
                                badge: '=(items.vNextcloud_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vNextcloud_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Plex Media Server
                                badge: '=(items.vPlex_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vPlex_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Portainer
                                badge: '=(items.vMedusa_Portainer_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vMedusa_Portainer_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: PostgreSQL
                                badge: '=(items.vPostgreSQL_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vPostgreSQL_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Redis
                                badge: '=(items.vRedis_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vRedis_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: norns
                    subtitle: Dad's openHAB server
                    badge: '=(items.vNorns_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.vNorns_Status.state === "ON") ? "green" : "red"'
                  slots:
                    accordion:
                      - component: oh-list
                        config:
                          accordionList: true
                          class:
                            - margin-left
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: Dad's openHAB
                                badge: '=(items.vDads_openHAB_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vDads_openHAB_Status.state === "ON") ? "green" : "red"'
                - component: oh-list-item
                  config:
                    title: Devices
                    subtitle: Individual Devices
                    badge: '=(items.DeviceStatuses.state === "ON") ? "ONLINE" : "OFFLINE"'
                    badgeColor: '=(items.DeviceStatuses.state === "ON") ? "green" : "red"'
                  slots:
                    accordion:
                      - component: oh-list
                        config:
                          accordionList: true
                          class:
                            - margin-left
                        slots:
                          default:
                            - component: oh-list-item
                              config:
                                title: GalaxyNote TinyCam Service
                                badge: '=(items.vGalaxyNote_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vGalaxyNote_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: HestiaPi
                                badge: '=(items.vHestiaPi_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vHestiaPi_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: MBR Sensors
                                badge: '=(items.vMBR_Sensors_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vMBR_Sensors_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: MBR Shelly 1
                                badge: '=(items.vMBR_Shelly_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vMBR_Shelly_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Nate's NR Sensors
                                badge: '=(items.vNateBR_Sensors_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vNateBR_Sensors_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Orbi AP
                                badge: '=(items.vOrbi_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vOrbi_Status.state === "ON") ? "green" : "red"'
                            - component: oh-list-item
                              config:
                                title: Orbi Satellite AP
                                badge: '=(items.vOrbi_Satellite_Status.state === "ON") ? "ONLINE" : "OFFLINE"'
                                badgeColor: '=(items.vOrbi_Satellite_Status.state === "ON") ? "green" : "red"'

Here is where I discovered my first mistake. I put a whole bunch of time into that widget and want to preserve it even if I decided to move it around on the Page or put it on other pages. I need this to be a custom widget is it’s stored separately from the Page. Enter the Widgets library.

First, copy all the YAML from the widget you just created to the clipboard. Next open the Developer Tools and then Widgets. Click the + icon and paste the YAML previously copied over the component and config entries. Enter meaningful values for the name, label, and such and some reasonable tags. Save it and you’ve now created your own reusable widget.

When adding a new widget to a page, there will be a “Personal Widgets” section you can select it from to drop it onto the page.

7 Likes