[OH3] Main UI - New „main_widget“ - development and testing [deprecated]

Sorry for bothering @JustinG, it was again a dumb typo i had. Got it working …

Forgive me, I’m feeling lost in space!
@Nic0205 @hmerk @rubenfuser Regarding color scheme for Navbar and tabs:

0_Color Scheme_v2.pdf (53.2 KB)

@hmerk Regarding the security widget: I’m struggling a lot to put all valuable info you gave us in a widget…
In my view, proceed with your way. It’s minimal and to the point. I’m just sharing my draft. It would be nice if you spend some time to review:

0_Security.pdf (53.9 KB)

I will check later today, already have some improvements in mind. I will try to combine both (your draft and my ideas)

Some early comments.
In general, information on cameras and motion sensors in such a list should be possible. What seems to be impossible is the time information for delta since last change. I have to think if there is a possibility to access pesistence data in expressions. Right now, I have no clue.
Only guess would be to work with calculated proxy items, but this would mean a lot of effort (additional items and rules for each camera and motion sensor)
If you want door and window states as well, effort is raising again.

Hello all…

just want to say, that i’m following this thread. Really good work here! I like the approach of using the semantic model showing in such a design.

please keep up the good work! will certainly use it! Unfortunately, I’m not a big help :wink: then make myself available as a tester :slight_smile:

5 Likes

Hi Hans-Jörg,

I tried a similar thing long time ago and ended up in maintaining a dedicated item per equipment holding the last activity and/or the last change:

This finally enabled me to show the time since last change in a widget by using the .fromNow() method:

badge: =dayjs(items[loop.i.name].state).fromNow()

E.g.:

Btw.: I’ve been following this devolopement silently so far and am impressed by the progress and the clean and modern design. It’s good to see the productive collaboration between you coders and designers. Keep it going!

3 Likes

This is also what I do. I go pretty simply though. I just use a proxy item and the timestamp profile for each item whose time of last change I need. No need for any additional rules. The timestamp is sufficient for my simple needs:
image

2 Likes

Thanks Guys, I hve seen all this before, but this might be quite a lot of additional items to create and the overall concept should be to minify the additional effort to set this all up.

So we have to decide wether this effort should be taken or not.
@Dimitris What’s your opinion on this ? Checking your screenshot, it qould be at least 17 additional items to be created.

Exactly, just a second link to the relevant channel by using the timestamp profile :+1:

@hmerk If we talking for the security widget then go for the simplest and easiest solution. What you have done with security widget in more than enough! The draft I’ve sent is some “not finished - not enough studied” idea!
Tommorow I will search further to enhance your widget. You know, to do some fancy stuff on it!!

1 Like

So right. Can you help me design another type of widget for that equipment? Just give me an example.

Let me check, might need some time.

Hi,

here the code for the stylesheet styled bottom navbar. Reduces code :wink:

uid: main_widget_poc
tags: []
props:
  parameters:
    - description: Set default color for Text
      label: Text color
      name: textColor
      required: false
      type: TEXT
    - default: RGB(96, 96, 96)
      description: Set default color for Text
      label: Bottom-Navbar-Color
      name: bnavColor
      required: false
      type: TEXT
    - default: Somewhere
      description: Name for your weather location
      label: Weather Location
      name: locationTitle
      required: false
      type: TEXT
    - context: item
      description: Name of scenes group item
      label: Scenes Group
      name: scenesGroup
      required: false
      type: TEXT
    - context: item
      description: Name of security group item
      label: Security Group
      name: securityGroup
      required: false
      type: TEXT
    - context: item
      description: Security Mode Item
      label: Security Mode
      name: securityMode
      required: false
      type: TEXT
    - context: item
      description: Security PIN Item
      label: Security PIN
      name: referencePIN
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Sep 25, 2022, 4:06:06 PM
component: f7-block
config:
  style:
    display: flex
    flex-direction: column
    height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-safe-area-top))
    justify-content: space-between
    margin: 0
    padding: 0
    width: 100%
    background: =(themeOptions.dark=="light") ? ("white"):("black")
    --menu-text-color: '= (!props.textColor) ? (themeOptions.dark=="light")? black : white : props.textColor'
    --f7-button-text-color: "#8c8c8c"
    --opmw-menu-text-color: =(themeOptions.dark=="light")?("#8C8C8C"):("#848484")
  stylesheet: >
    .selected_menu_item {
      color: var(--menu-text-color);
      text-decoration-color: #F8BB00 !important;
      text-decoration: underline;
      text-underline-offset: 2.px;
      font-weight: bold;
    } 

    .unselected_menu_item {
      color: #8C8C8C;
      font-weight: 300;
    }
    
    
    .selected_bottom_navbar_item {
     color: white;
     
     font-size: 12px;
     height: auto;
     --f7-button-bg-color: transparent;  
     

    }  
    
    

    .unselected_bottom_navbar_item {
     
     color: "#8c8c8c";
     font-size: 12px;
     height: auto;
     --f7-button-bg-color: transparent  
    } 
    

    
    
    
    
    
    
    
slots:
  default:
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
      slots:
        default:
          - component: f7-segmented
            config:
              style:
                flex: 1 1 auto
                justify-content: center
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: baseMenu
                    fragment: true
                    in:
                      - name: Home
                      - name: Floors
                      - name: Rooms
                    map: loop.baseMenu.name
                    sourceType: array
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: objVar
                          actionVariableValue:
                            selectSection: ="SECTION" + loop.baseMenu_idx
                          large: true
                          class: '=(vars.objVar && (vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx)) ? "selected_menu_item" : "unselected_menu_item"'
                          style:
                            font-size: 24px
                            width: 25%
                          text: =loop.baseMenu
          - component: f7-row
            config:
              style:
                align-items: center
                display: flex
                flex-direction: row
                flex-wrap: nowrap
                height: 2em
                justify-content: space-between
                width: 100%
              visible: false
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexHome
                    actionVariableValue: =(vars.buttonIndexHome || 0) - 1
                    iconF7: chevron_left
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
                - component: oh-repeater
                  config:
                    for: menuArray
                    fragment: true
                    sourceType: itemsWithTags
                    itemTags: Floor
                    fetchMetadata: widgetOrder
                    map: loop.menuArray_source
                  slots:
                    default:
                      - component: f7-row
                        config:
                          style:
                            display: flex
                            height: 2em
                            justify-content: center
                            overflow: hidden
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: menuButtonHome
                                fragment: true
                                in: =loop.menuArray
                                filter: loop.menuArray_idx == 0
                                map: ((loop.menuButtonHome.metadata && loop.menuButtonHome.metadata.widgetOrder && loop.menuButtonHome.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonHome_idx
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: variable
                                      actionVariable: floor
                                      actionVariableValue: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].name
                                      style:
                                        flex: 0 0 auto
                                        height: 2em
                                        order: =(((vars.buttonIndexHome || 0) % loop.menuButtonHome_source.length) + loop.menuButtonHome_source.length + loop.menuButtonHome_idx) % loop.menuButtonHome_source.length
                                      text: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].label
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexHome
                    actionVariableValue: =(vars.buttonIndexHome || 0) + 1
                    iconF7: chevron_right
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
          - component: f7-row
            config:
              style:
                align-items: center
                display: flex
                flex-direction: row
                flex-wrap: nowrap
                height: 2em
                justify-content: center
                width: 100%
              visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION1") ? true : false : false'
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexFloor
                    actionVariableValue: =(vars.buttonIndexFloor || 0) - 1
                    iconF7: chevron_left
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
                - component: oh-repeater
                  config:
                    for: menuArray
                    fragment: true
                    sourceType: itemsWithTags
                    itemTags: Floor
                    fetchMetadata: widgetOrder
                    map: loop.menuArray_source
                  slots:
                    default:
                      - component: f7-row
                        config:
                          style:
                            display: flex
                            height: 2em
                            justify-content: center
                            overflow: hidden
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: menuButtonFloor
                                fragment: true
                                in: =loop.menuArray
                                filter: loop.menuArray_idx == 0
                                map: ((loop.menuButtonFloor.metadata && loop.menuButtonFloor.metadata.widgetOrder && loop.menuButtonFloor.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonFloor_idx
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: variable
                                      actionVariable: floor
                                      actionVariableValue: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].name
                                      class: '=(vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
                                      style:
                                        flex: 0 0 auto
                                        height: 2em
                                        order: =(((vars.buttonIndexFloor || 0) % loop.menuButtonFloor_source.length) + loop.menuButtonFloor_source.length + loop.menuButtonFloor_idx) % loop.menuButtonFloor_source.length
                                        text-underline-offset: 4px
                                      text: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].label
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexFloor
                    actionVariableValue: =(vars.buttonIndexFloor || 0) + 1
                    iconF7: chevron_right
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
          - component: f7-row
            config:
              style:
                align-items: center
                display: flex
                flex-direction: row
                flex-wrap: nowrap
                height: 2em
                justify-content: center
                width: 100%
              visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION2") ? true : false : false'
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexRoom
                    actionVariableValue: =(vars.buttonIndexRoom || 0) - 1
                    iconF7: chevron_left
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
                - component: oh-repeater
                  config:
                    for: menuArrayRoom
                    fragment: true
                    sourceType: itemsWithTags
                    itemTags: =vars.floor
                    fetchMetadata: widgetOrder
                    map: loop.menuArrayRoom_source
                  slots:
                    default:
                      - component: f7-row
                        config:
                          style:
                            display: flex
                            height: 2em
                            justify-content: center
                            overflow: hidden
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: menuButtonRoom
                                fragment: true
                                in: =loop.menuArrayRoom
                                filter: loop.menuArrayRoom_idx == 0
                                map: ((loop.menuButtonRoom.metadata && loop.menuButtonRoom.metadata.widgetOrder && loop.menuButtonRoom.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonRoom_idx
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: variable
                                      actionVariable: room
                                      actionVariableValue: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].name
                                      class: '=(vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
                                      style:
                                        flex: 0 0 auto
                                        height: 2em
                                        order: =(((vars.buttonIndexRoom || 0) % loop.menuButtonRoom_source.length) + loop.menuButtonRoom_source.length + loop.menuButtonRoom_idx) % loop.menuButtonRoom_source.length
                                        text-underline-offset: 4px
                                      text: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].label
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexRoom
                    actionVariableValue: =(vars.buttonIndexRoom || 0) + 1
                    iconF7: chevron_right
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
    - component: widget:main_widget_Home_Card
      config:
        locationTitle: =props.locationTitle
        scenesGroup: =props.scenesGroup
        securityGroup: =props.securityGroup
        securityMode: =props.securityMode
        referencePIN: =props.referencePIN
    - component: widget:main_widget_Floor_Card
    - component: widget:main_widget_Room_Card
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
          margin-bottom: -4em
          background: =props.bnavColor
          border-radius: 0px 0px 10px 10px
        visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? true : false : false'
      slots:
        default:
          - component: f7-segmented
            config:
              class:
                - segmented-strong
              style:
                --f7-segmented-strong-between-buttons: 0px
                --f7-segmented-strong-bg-color: transparent
                --f7-segmented-strong-button-font-weight: 300
                --f7-segmented-strong-button-hover-bg-color: rgba(255, 255, 255, 0.15)
                --f7-segmented-strong-padding: 0px
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Security
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.objVar.selectThing=="Security" ? true : false'
                    icon-f7: shield_fill
                    iconColor: '=items[props.securityMode].state != "disarmed"  ? "red" : "gray"'
                    iconSize: 20
                    style:
                      --f7-button-bg-color: transparent
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.objVar.selectThing=="Security" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.objVar.selectThing=="Security" ? "black" : "white"'
                      font-size: 12px
                      height: auto
                    text: Security
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Scenes
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.objVar.selectThing=="Scenes" ? true : false'
                    icon-f7: rectangle_on_rectangle_angled
                    iconColor: '=vars.objVar.selectThing=="Scenes" ? "black" : "white"'
                    iconSize: 20
                    style:
                      --f7-button-bg-color: transparent
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.objVar.selectThing=="Scenes" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.objVar.selectThing=="Scenes" ? "black" : "white"'
                      font-size: 12px
                      height: auto
                    text: Scenes
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Weather
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.objVar.selectThing=="Weather" ? true : false'
                    icon-f7: cloud
                    iconColor: '=vars.objVar.selectThing=="Weather" ? "black" : "white"'
                    iconSize: 20
                    style:
                      --f7-button-bg-color: transparent
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.objVar.selectThing=="Weather" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.objVar.selectThing=="Weather" ? "black" : "white"'
                      font-size: 12px
                      height: auto
                    text: Weather
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Energy
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.objVar.selectThing=="Energy" ? true : false'
                    icon-f7: bolt_fill
                    iconColor: '=vars.objVar.selectThing=="Energy" ? "black" : "white"'
                    iconSize: 20
                    style:
                      --f7-button-bg-color: transparent
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.objVar.selectThing=="Energy" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.objVar.selectThing=="Energy" ? "black" : "white"'
                      font-size: 12px
                      height: auto
                    text: Energy
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
          margin-bottom: -4em
          background: =props.bnavColor
          border-radius: 0px 0px 10px 10px
        visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? false : true : false'
      slots:
        default:
          - component: f7-segmented
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Lights
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Lights")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: lightbulb_fill
                    
                    text: Lights
                    
                    
                    
                    
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Rollers
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Rollers")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: archivebox
                    text: Shades
                    
                    
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Climate
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Climate")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: snow
                    text: Climate
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Appliances
                    iconMaterial: power
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Appliances")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    text: Appliances

Great, thanks !

@ Team. Finally I’m home.
Your poor designer needs some help to enjoy your achievements!

I’m quite sure that i have create a proper semantic model :smiling_face: (i see @hmerk laughing out loud…) but I can’t hide the standard OH nav bar. Is there some special code to copy-paste it at page code?

@Nic0205 can you help me Buddy?

Why should I
While developing, I still find issues in my model an fix them. There is alway room for improvement….

Here is the code for the page

config:
  label: openPage
  sidebar: true
  hideNavbar: true
  showFullscreenIcon: false
  hideSidebarIcon: true
  style:
    --f7-block-padding-horizontal: 0px
    --f7-navbar-height: 0
blocks:
  - component: oh-block
    config:
      stylesheet: |
        .block:first-child{
          margin-top: 15px;
          }
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: widget:main_widget
                      config:
                        locationTitle:
                        scenesGroup:
                        securityGroup:
                        securityMode:
                        referencePIN:
masonry: null
grid: []

1 Like

@Team, following this discussion

we should overthink the scenes card and make it stateless….

@Dimitris Here is a little spoiler of what I am just working on :wink:

2 Likes

… I forgot to implement the stylesheet for the navbar for the home menu.

Please see updated code:

uid: main_widget
tags: []
props:
  parameters:
    - description: Set default color for Text
      label: Text color
      name: textColor
      required: false
      type: TEXT
    - default: RGB(96, 96, 96)
      description: Set default color for Text
      label: Bottom-Navbar-Color
      name: bnavColor
      required: false
      type: TEXT
    - default: Somewhere
      description: Name for your weather location
      label: Weather Location
      name: locationTitle
      required: false
      type: TEXT
    - context: item
      description: Name of scenes group item
      label: Scenes Group
      name: scenesGroup
      required: false
      type: TEXT
    - context: item
      description: Name of security group item
      label: Security Group
      name: securityGroup
      required: false
      type: TEXT
    - context: item
      description: Security Mode Item
      label: Security Mode
      name: securityMode
      required: false
      type: TEXT
    - context: item
      description: Security PIN Item
      label: Security PIN
      name: referencePIN
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Sep 25, 2022, 4:06:06 PM
component: f7-block
config:
  style:
    display: flex
    flex-direction: column
    height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-safe-area-top))
    justify-content: space-between
    margin: 0
    padding: 0
    width: 100%
    background: =(themeOptions.dark=="light") ? ("white"):("black")
    --menu-text-color: '= (!props.textColor) ? (themeOptions.dark=="light")? black : white : props.textColor'
    --f7-button-text-color: "#8c8c8c"
    --opmw-menu-text-color: =(themeOptions.dark=="light")?("#8C8C8C"):("#848484")
  stylesheet: >
    .selected_menu_item {
      color: var(--menu-text-color);
      text-decoration-color: #F8BB00 !important;
      text-decoration: underline;
      text-underline-offset: 2.px;
      font-weight: bold;
    } 

    .unselected_menu_item {
      color: #8C8C8C;
      font-weight: 300;
    }
    
    
    .selected_bottom_navbar_item {
     color: white;
     
     font-size: 12px;
     height: auto;
     --f7-button-bg-color: transparent;  
     

    }  
    
    

    .unselected_bottom_navbar_item {
     
     color: "#8c8c8c";
     font-size: 12px;
     height: auto;
     --f7-button-bg-color: transparent  
    } 
    

    
    
    
    
    
    
    
slots:
  default:
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
      slots:
        default:
          - component: f7-segmented
            config:
              style:
                flex: 1 1 auto
                justify-content: center
                margin-left: 2%
                margin-right: 2%
                gap: 10px
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: baseMenu
                    fragment: true
                    in:
                      - name: Home
                      - name: Floors
                      - name: Rooms
                    map: loop.baseMenu.name
                    sourceType: array
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: objVar
                          actionVariableValue:
                            selectSection: ="SECTION" + loop.baseMenu_idx
                          large: true
                          class: '=vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx ? "selected_menu_item" : "unselected_menu_item"'
                          style:
                            font-size: 24px
                            font-weight: 200
                            flex: 0 1 auto
                            width: auto
                          text: =loop.baseMenu
          - component: f7-row
            config:
              style:
                align-items: center
                display: flex
                flex-direction: row
                flex-wrap: nowrap
                height: 2em
                justify-content: space-between
                width: 100%
              visible: false
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexHome
                    actionVariableValue: =(vars.buttonIndexHome || 0) - 1
                    iconF7: chevron_left
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
                - component: oh-repeater
                  config:
                    for: menuArray
                    fragment: true
                    sourceType: itemsWithTags
                    itemTags: Floor
                    fetchMetadata: widgetOrder
                    map: loop.menuArray_source
                  slots:
                    default:
                      - component: f7-row
                        config:
                          style:
                            display: flex
                            height: 2em
                            justify-content: center
                            overflow: hidden
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: menuButtonHome
                                fragment: true
                                in: =loop.menuArray
                                filter: loop.menuArray_idx == 0
                                map: ((loop.menuButtonHome.metadata && loop.menuButtonHome.metadata.widgetOrder && loop.menuButtonHome.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonHome_idx
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: variable
                                      actionVariable: floor
                                      actionVariableValue: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].name
                                      style:
                                        flex: 0 0 auto
                                        height: 2em
                                        order: =(((vars.buttonIndexHome || 0) % loop.menuButtonHome_source.length) + loop.menuButtonHome_source.length + loop.menuButtonHome_idx) % loop.menuButtonHome_source.length
                                      text: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].label
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexHome
                    actionVariableValue: =(vars.buttonIndexHome || 0) + 1
                    iconF7: chevron_right
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
          - component: f7-row
            config:
              style:
                align-items: center
                display: flex
                flex-direction: row
                flex-wrap: nowrap
                height: 2em
                justify-content: center
                width: 100%
              visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION1") ? true : false : false'
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexFloor
                    actionVariableValue: =(vars.buttonIndexFloor || 0) - 1
                    iconF7: chevron_left
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
                - component: oh-repeater
                  config:
                    for: menuArray
                    fragment: true
                    sourceType: itemsWithTags
                    itemTags: Floor
                    fetchMetadata: widgetOrder
                    map: loop.menuArray_source
                  slots:
                    default:
                      - component: f7-row
                        config:
                          style:
                            display: flex
                            height: 2em
                            justify-content: center
                            overflow: hidden
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: menuButtonFloor
                                fragment: true
                                in: =loop.menuArray
                                filter: loop.menuArray_idx == 0
                                map: ((loop.menuButtonFloor.metadata && loop.menuButtonFloor.metadata.widgetOrder && loop.menuButtonFloor.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonFloor_idx
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: variable
                                      actionVariable: floor
                                      actionVariableValue: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].name
                                      class: '=(vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
                                      style:
                                        flex: 0 0 auto
                                        height: 2em
                                        order: =(((vars.buttonIndexFloor || 0) % loop.menuButtonFloor_source.length) + loop.menuButtonFloor_source.length + loop.menuButtonFloor_idx) % loop.menuButtonFloor_source.length
                                        text-underline-offset: 4px
                                      text: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].label
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexFloor
                    actionVariableValue: =(vars.buttonIndexFloor || 0) + 1
                    iconF7: chevron_right
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
          - component: f7-row
            config:
              style:
                align-items: center
                display: flex
                flex-direction: row
                flex-wrap: nowrap
                height: 2em
                justify-content: center
                width: 100%
              visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION2") ? true : false : false'
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexRoom
                    actionVariableValue: =(vars.buttonIndexRoom || 0) - 1
                    iconF7: chevron_left
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
                - component: oh-repeater
                  config:
                    for: menuArrayRoom
                    fragment: true
                    sourceType: itemsWithTags
                    itemTags: =vars.floor
                    fetchMetadata: widgetOrder
                    map: loop.menuArrayRoom_source
                  slots:
                    default:
                      - component: f7-row
                        config:
                          style:
                            display: flex
                            height: 2em
                            justify-content: center
                            overflow: hidden
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                for: menuButtonRoom
                                fragment: true
                                in: =loop.menuArrayRoom
                                filter: loop.menuArrayRoom_idx == 0
                                map: ((loop.menuButtonRoom.metadata && loop.menuButtonRoom.metadata.widgetOrder && loop.menuButtonRoom.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonRoom_idx
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: variable
                                      actionVariable: room
                                      actionVariableValue: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].name
                                      class: '=(vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
                                      style:
                                        flex: 0 0 auto
                                        height: 2em
                                        order: =(((vars.buttonIndexRoom || 0) % loop.menuButtonRoom_source.length) + loop.menuButtonRoom_source.length + loop.menuButtonRoom_idx) % loop.menuButtonRoom_source.length
                                        text-underline-offset: 4px
                                      text: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].label
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: buttonIndexRoom
                    actionVariableValue: =(vars.buttonIndexRoom || 0) + 1
                    iconF7: chevron_right
                    style:
                      color: "#F8BB00"
                      flex: 0 0 auto
                      height: 2em
    - component: widget:main_widget_Home_Card
      config:
        locationTitle: =props.locationTitle
        scenesGroup: =props.scenesGroup
        securityGroup: =props.securityGroup
        securityMode: =props.securityMode
        referencePIN: =props.referencePIN
    - component: widget:main_widget_Floor_Card
    - component: widget:main_widget_Room_Card
  
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
          margin-bottom: -4em
          background: =props.bnavColor
          border-radius: 0px 0px 10px 10px
        visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? true : false : false'
      slots:
        default:
          - component: f7-segmented
            config:
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Security
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Security")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: shield_fill
                    iconColor: '=items[props.securityMode].state != "disarmed"  ? "red" : "gray"'
                   
                    text: Security
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Scenes
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Scenes")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: rectangle_on_rectangle_angled
                    
                    text: Scenes
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Weather
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Weather")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: cloud
                   
                    text: Weather
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Energy
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Energy")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: bolt_fill
                   
                    text: Energy
                    
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
          margin-bottom: -4em
          background: =props.bnavColor
          border-radius: 0px 0px 10px 10px
        visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? false : true : false'
      slots:
        default:
          - component: f7-segmented
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Lights
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Lights")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: lightbulb_fill
                    
                    text: Lights
                    
                    
                    
                    
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Rollers
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Rollers")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: archivebox
                    text: Shades
                    
                    
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Climate
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Climate")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    icon-f7: snow
                    text: Climate
                    
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: objVar
                    actionVariableValue:
                      selectSection: =vars.objVar.selectSection
                      selectThing: Appliances
                    iconMaterial: power
                    class: '=(vars.objVar && (vars.objVar.selectThing=="Appliances")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
                    text: Appliances
1 Like

@hmerk wow! WOW! It seems like a fully loaded security app!! Definitely many+++ for the OH platform. Now, the “fancy stuff” sticks with your widget! :melting_face: