Building Pages in the OH3 UI: documentation draft (2/3)

I think this would be a neat addition for widget creators - the context sounds like a good idea and the extra lines of context-code should not bother too much.

I bridged the page-links by adding f7-links or using nested oh-list-elements until now (with some annoying drawbacks) - so yes, the page-context definitely helps. :slight_smile:

There are 3 more questions which maybe fits here - if not, tell me and I will move them.

  • Is there a reason that almost all f7-components are somewhat rebuild as a ‘custom’ oh-widget besides timeline, datetime pickers and a few others? Or is it just work-in-progress?

  • I ask this, because I saw a question in this forum today, where someone was asking for some kind of “execution-timer” in OH3, so I gave myself a homework, trying to build one.
    While doing so, I stucked at the point where I implemented the ‘f7-input’ for the time-selection and want it to talk with the oh-button that should send the execution-time to selected openhab-item.

    • Can you work with variables inside the YAML structure to exchange values between different components? Or is this a limitation due to the missing oh- version of this component?
  • Is there a way to set parameters for the whole page component, for things like page-background etc.

That’s because the f7 components alone aren’t “wired” to anything and in some cases some openHAB-specific logic is necessary to make them useful. For example, the f7-toggle alone won’t do anything, that’s why there’s a oh-toggle which allows it to control an item and reflect its state.

No, the components cannot share information between themselves, so this kind of advanced interactivity is not currently supported. If there’s a need for an “oh-input” in the system library I’m sure it will be added eventually.
The idea behind the custom widgets was more to allow building custom layouts around the existing widgets in the system library - sliders, labels, toggles, buttons; for example, a complete thermostat control with a knob to change the setpoint, some buttons and a temperature/humidity reading - than to provide missing logic or interaction flows. But it’s pretty new and largely untested in the field so the feature set might be extended in the future.

Setting a page background would have to be implemented in the page component itself, it probably won’t work out of the box - the oh-layout-page is not actually based on f7-page, the actual f7-page is higher in the DOM hierarchy.

However, while it’s not done yet, it’s very much on the todo list to add the ability to define props for pages similarly to custom widgets; in other words, parameterized pages. If you have, say, multiple
identical thermostats or other devices and you designed a full page to control one, you wouldn’t have to duplicate that page for every device. You’d design the page once and for all and define props to configure the items, then you could set those props where that page is referenced (for instance in a tab of a tabbed page, or for certains types of actions: navigate, popup, sheet, etc.).
I hope I’ll explain this better when I get around to writing the 3rd article in this series.

This makes sense and reflects my results in creating some custom widgets out of f7-components where there is no oh-equivalent - partly possible but a bit tricky to nest oh-components (with already existing logic and styling behind it) inside of f7-components.

These 2 requirements feels somewhat related to each other, arent they?
If there is an input-component, there have to be some way to define an action trigger (like e.g. a button) to send the value to the item?! A similar approch as in the gauge or slider widget (display the current state and setting the new state in the same element) wouldn´t work here or at least wouldn´t be as dynamic when it comes to widget creation, or am I wrong?

I would definitely vote for this feature, as I feel its missing a long time now. Where would be the right place to make my interest on this visible, find other people with the same need and bringing this topic to the backlog? Is a guithub issue suitable for this or should I open a thread in this forum?

I´m with you, that widgets shouldn´t have more logic than the system behind it - but I definitely see the need for a deeply customizable UI which IMHO is key for a good UX.
Especially when it comes to motivate new people entering the world of homeautomation and let OH stands out with it´s flexibility and beauty (this is a thing, every homeautomation system struggles with the most as it feels).

The current set of custom components are already nice to build up some fancy looking widgets, although some of them are a bit complex in its base structure, what makes it hard to build things around them (e.g. oh-list-card).

If this base component-set will grow and things like the input-components will be implemented, I see an even greater future for OH and a lot of fun for widget creators.
While fiddling around with everything, I was able to ‘clone’ nearly every image (of the first page :smiley:) for the google search term “smarthome ui concept” (although obviously not all of them interacting with OH items right now) - LOVING IT!

Glad to hear :slight_smile:

This will be very helpfull!

Thanks again for all your efforts for this community and your quick and detailed answers.

2 Likes

If you have specific pain points please feel free to open issues in Issues · openhab/openhab-webui · GitHub (preferably, rather than here).

Thinking about that a bit more, having an ability to set variables and then access them in expressions looks doable, and might just work for this use case. Something like:

- component:oh-input
  config:
    type: datetime
    variable: alarmTime # sets widget-local variable "alarmTime" on change
- component: oh-button
  config:
    action: command
    actionItem: AlarmTime
    actionCommand: =vars.alarmTime # "vars" contains a key-value map of variables

The existing widgets like sliders, steppers and knob could also be extended to set a variable instead of sending commands to an item directly - so you could confirm the new state with a separate button and probably other things too :thinking:

Really? That’s awesome! If you can share some of that I (and certainly others) would be very interested!

1 Like

(By the way: there’s a marketplace proposal being discussed/in the works to distribute out-of-distro add-ons, rule templates and more, I’m advocating for it to be community-moderated like the HABPanel widget gallery and custom widgets would also hopefully be able to be distributed that way.)

Perfect! I´ll do that.
For a non-technical person its sometimes hard to find the right place for your concern. :slight_smile:

If this would be an optional addition to each widget component, this would be a blast, I think :+1: - you can count on me as a beta tester!

I´ll do so! Have to do some beauty work on the YAMLs and making screenshots later this day, so I can post them here tonight, I think.


Sorry, but didnt find any time atm due to sick kid and wife - and my personal demand prohibits me to just clash in some pictures here, without offering any source implementing and develop the seen things for yourself.

So I just cobbled together at least one widget, that is (with a little effort) reussable for different cases.

It looks like this and supports the most oh-list-components for the bottom row (slider, button, stepper, toggle and more or less icons). It´s working mostly correct on all devices I tested it with (web, ios, android)
2020-09-22 00-02-09
brightness_variants

Further more I already roughly cleaned up the color-changing widget of this ‘theme’, which looks something like:
color_example

All of the color and icon ideas came from a dribble UI concept I found via google from Amogh Srivastava (thx! Smart Home UI Concept by Amogh Srivastava on Dribbble)

You can find the first itteration of the brightness example from above on a github repo - rebuild it, extend it, use it, do whatever you like: GitHub - rgrollfitz/oh3-widgets

Disclaimer: I only have basic experience in working with css and none with the infinite nested yaml-structure. So please keep this in mind while watching the repo. :slight_smile:

Having some more conecept ideas lying around here and will finish and post them in this forum, as soon as I find time.

At last, I want to attach some notes (mostly questions :stuck_out_tongue:) I took during the process of creating these widgets:

  • Would be nice to have a way to react on the different breakpoints via YAML (similar to media queries)
  • oh-link and oh-image doesn´t support setting actions (it seems, that just oh-button & oh-list-item offers this functionality?!)
  • No access to the different css sub classes like :hover (annoying e.g. in case of misusing oh-button as a clickable overlay)
  • No standalone oh-icon class available - would be nice to have one
  • Not possible to use math functions or exeptions in actionCommands
  • The oh-slider item reports an error in the widget-config, if you select a 0 as min-value (it works flawelessly if you set it via yaml)
  • Nice to have: Interacting with svg parameters like we could do in habpanel, to make things move, spin or glow.
  • Expressions doesnt work in styles
  • Boolean toogle in settings isnt working for things like ‘visible:true/false’ (tested on oh-stepper-item) - maybe there are some extra “”, which shouldnt be there?
    • Workaround: ‘class: =props.yourProp ? props.yourProp : “display-none”’
  • Is it possible to use transformation in rules?
  • How to change the site-content depending on a selection made in an element like e.g. a header-slider for selecting the rooms?
9 Likes

That looks awesome @RGroll! I’m glad you’re giving this concept a spin so thoroughly and apparently are having some success with it, it’s encouraging. Many thanks for sharing your work as well.

Your feedback mostly makes sense, I can’t address every point you raised individually now but will later (“expressions don’t work in styles” is particularly true), I think the majority of them can be somewhat resolved one way or another.

1 Like

Can someone smarter than me post an example of a collapsible list? I’ve spent too much time on this already. It seems like the following should work:

component: oh-list-card
config:
  accordionList: true
  title: All Services Status
  footer: Online status of home automation related services
slots:
  default:
    - component: oh-label-item
      config:
        item: ServiceStatuses
        title: All Services
        subtitle: When OFF one or more services are offline
        icon: oh:network
      slots:
        accordion:
          - component: oh-label-item
            config:
              item: vArgus_Status
              title: argus
              subtitle: Home automation server
              icon: oh:network
            slots:
              accordion:
                - component: oh-label-item
                  config:
                    item: vInfluxDB_Status
                    title: InfluxDB
                    subtitle: Home auotmation database server
                    icon: oh:network
          - component: oh-label-item
            config:
              item: vCerberos_Status
              title: cerberos
              subtitle: Garage sensors and actuators
              icon: oh:network
          - component: oh-label-item
            config:
              item: vFafnir_Status
              title: fafnir
              subtitle: NAS server
              icon: oh:network

Thanks!
But when I try the above all I see is

I’m clearly doing something wrong for the subsequent list Items after “argus” but I can’t see what that would be.

I an just guessing. Is there a slot and accordion to much after argus??

My intent was to have argus also be an accordion that opens up. So I’d have three levels, like:

All Service
    argus
        InfluxDB
    cerberos
    fafnir

Based on the examples I assumed this was how to do it but I guess it’s not and I’m stumped.

Can’t do it either :cry:
(which is perhaps telling)
I’ll see how to achieve this and make some changes if need be.

1 Like

I was able to do one level of depth like this, but no further:

component: oh-list-card
config:
  accordionList: true
slots:
  default:
    - component: oh-list-item
      config:
        accordionItem: true
        title: Depth 0
        after: =1+2
      slots:
        accordion:
          - component: oh-list
            slots:
              default:
                - component: oh-list-item
                  config:
                    title: Depth 1 - Item 1
                    after: =2+3
                - component: oh-list-item
                  config:
                    title: Depth 1 - Item 2
                    after: =3+4
                - component: oh-list-item
                  config:
                    title: Depth 1 - Item 3
                    after: =4+5

2020-10-17_00-45-06

I got it working with a few limitations and some nesting :crazy_face:

  • Nested ‘icon: xy’ would work but will mess up the accordion layout a bit

// EDIT

  • I added some real items for testing now and it seems, that the ‘item’ parameter isn´t present in ‘oh-list-item’ so you have to trick around this with an expression like ‘after: =items.vArgus_Status.state’, which should also work for the badge, if you like it.

//Edit2:

  • Contrary to my statement that ‘subtitle:’ won´t work in ‘oh-label-item’ - its just depending on the ‘mediaList: true’ parameter - if set, everything works fine. :wink:

nestedAccordion

uid: nestedAccordion
tags:
  - nested
  - accordion
  - list
component: oh-list-card
config:
  title: All Services Status
  accordionList: true
  footer: Online status of home automation related services
slots:
  default:
    - component: oh-list-item
      config:
        title: All Services
        icon: oh:network_purple
        badge: " OK "
        badgeColor: green
      slots:
        accordion:
          - component: oh-list-card
            config:
              accordionList: true
              noBorder: true
              noShadow: true
              outline: true
            slots:
              default:
                - component: oh-list-item
                  config:
                    title: "argus"
                    after: =items.vArgus_Status.state
                    accordionList: true
                    noBorder: true
                    noShadow: true
                    outline: true
                  slots:
                    accordion:
                      - component: oh-label-item
                        config:
                          item: vInfluxDB_Status
                          title: "influxDB"                    
                - component: oh-label-item
                  config:
                    item: vCerberos_Status
                    title: "cerberos"
                - component: oh-label-item
                  config:
                    item: vFafnir_Status
                    title: "fafnir"
                - component: oh-list-item
                  config:
                    title: Show analysis
                    listButton: true
                    action: analyzer
                    #actionAnalyzerCoordSystem:
                    #actionAnalyzerItems:
3 Likes

Could anybody lead me in the right direction using multiple javascript functions inside of expressions - it seems that there are some particularities in the usage.

To be more accurate, I try to split and rearrange multiple variables if the value isn´t null. From what google teached me, it should work like that (with some extra brackets on the array, which seems to be one of the above mentioned particularities of the OH-expressions):

=([vars.contact.split(";")[0],vars.contact.split(";")[1],vars.contact.split(";")[2]]).filter(boolean).join(";")

This returns ‘TypeError: undefined is not a function’

If I remove the filter, everything works fine, but it adds the delimiter, even if the value is null.

=([vars.contact.split(";")[0],vars.contact.split(";")[1],vars.contact.split(";")[2]]).join(";")

Anoyone, that are more experienced in using javascript, has an idea?

Thank you!

The expression language is not actually JavaScript, it’s based on an expression parser (GitHub - EricSmekens/jsep: JavaScript Expression Parser), so while it does resemble JavaScript code (from the jsep readme):

It can parse JavaScript expressions but not operations. The difference between expressions and operations is akin to the difference between a cell in an Excel spreadsheet vs. a proper JavaScript program.

Therefore there are a number of limitations, for instance you cannot use methods that accept functions as a parameter, like the arrays’ map or filter, because it cannot parse them.

Good to know and thanks for the link. I´ll try to learn what´s possible and what`s not. :slight_smile:

Another question regarding the option to set property values on some actions called ‘actionModalConfig’ in YAML - How to set them? (there are no options given in the widget-configuration)

And what exactly are these ‘property values’? Are these the ones mentioned in the framework7 documentation? (e.g. https://framework7.io/vue/popup.html#popup-properties) or is it a way to set the declared properties for the widget itself?

Both of these thoughts doesn´t work in my tests.

Is there any writeup on this feature? Best case (from my point-of-view) would be that I can also use this to set a popup title and manipulate css-classes of the popup (but that is wishful thinking) :stuck_out_tongue:

It’s for the widget. See the keypad example here: Widgets: context variables, add oh-input by ghys · Pull Request #356 · openhab/openhab-webui · GitHub

I think it will be part of the 3rd page in this series, which I still have to write.
If the root component of your widget defines a “label” config property it will be the title of the popup.
For example in the keypad example adding label: Please Input Pin to the root f7-block.
Altering CSS cannot be done now, I’m aware you requested it ([MainUI] Customize css of pages/popups · Issue #408 · openhab/openhab-webui · GitHub)

Ah okay, got it!

And tested this already by accident, but obviously it only works if the root component is an f7-block.
So I´ll try to wait patiently for your work on the mentioned request. :slight_smile:

On the topic of this request - I managed it to create a widget with a custom background already (at least for the popup-case)


Thanks again!

7 Likes

Would you mind providing your Source code?

Looks great!

I think it would be best to open a new topic in the UI category (UIs - openHAB Community, maybe there could be a dedicated one) to discuss new widgets like this. I can do the same for the keypad.

3 Likes