I was just thinking that would be nice if you can enable/ disable rules (and not editing or creating new one!!s). And yes, a link to OH rules page seems a very good idea.
@Nic0205 @hmerk @rubenfuser So, our milestone is this:
Home menu: sub menu would be only the tab bar on footer
Floors menu: Sub menu on header and tab bar for filtering
Room menu: Sub menu on header and tab bar for filtering
Befor @hmerk and @Nic0205 starts firing up, ithat would be graet if I have your approval.
To be honest I’m quite understand what you mean…
Absolutely not, as you need admin rights for that!
Ahh - I see. thank you works like a charm now - but only after pressing one of the menu buttons once.
Until pressing a button the color is red / dark orange. It seems that the stylesheet takes effect after clicking/ performing the action and not direct after loading the widget…
I cannot see where this red is defined in the code - could you have a quick review on it?
EDIT: The color is “#E64A19” and this is the css variable var(--f7-button-text-color,var(--f7-theme-color))
EDIT2: tried it this way and it works (code is updated):
--f7-button-text-color: "#8c8c8c"
But don’t know if this is a good idea…
How could I define not to use this but the css defined in the widget…?
uid: main_widget
tags: []
props:
parameters:
- default: black
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: true
type: TEXT
parameterGroups: []
timestamp: Sep 24, 2022, 6:59:04 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
widht: 100vh
--menu-text-color: =props.textColor
--f7-button-text-color: "#8c8c8c"
stylesheet: >
.selected_menu_item {
color: var(--menu-text-color);
font-weight: bold;
text-decoration-color: #F8BB00 !important;
text-decoration: underline;
text-underline-offset: 2.px;
}
.unselected_menu_item {
color: #8C8C8C;
} .chevron {
color: #F8BB00;
}
slots:
default:
- component: f7-block
config:
style:
flex: 0 0 auto
overflow: scroll
slots:
default:
- component: f7-segmented
config:
style:
flex: 1 1 auto
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
class: '=(vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx) ? "selected_menu_item" : "unselected_menu_item"'
style:
font-size: 28px
font-weight: 200
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
class: chevron
style:
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
fetchMetadata: widgetOrder
for: menuArray
fragment: true
itemTags: Floor
map: loop.menuArray_source
sourceType: itemsWithTags
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
filter: loop.menuArray_idx == 0
for: menuButtonHome
fragment: true
in: =loop.menuArray
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
class: chevron
style:
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
class: chevron
style:
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
fetchMetadata: widgetOrder
for: menuArray
fragment: true
itemTags: Floor
map: loop.menuArray_source
sourceType: itemsWithTags
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
filter: loop.menuArray_idx == 0
for: menuButtonFloor
fragment: true
in: =loop.menuArray
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
style:
color: '=vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name) ? textColor : "#8C8C8C"'
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-decoration: underline
text-decoration-color: '=vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name) ? "#F8BB00" : "transparent"'
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
class: chevron
style:
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:
fetchMetadata: widgetOrder
for: menuArrayRoom
fragment: true
itemTags: =vars.floor
map: loop.menuArrayRoom_source
sourceType: itemsWithTags
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
filter: loop.menuArrayRoom_idx == 0
for: menuButtonRoom
fragment: true
in: =loop.menuArrayRoom
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
style:
color: '=vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name) ? textColor : "#8C8C8C"'
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-decoration: underline
text-decoration-color: '=vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name) ? "#F8BB00" : "transparent"'
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: f7-block
config:
style:
flex: 1 1 auto
margin-bottom: -1em
margin-top: -1em
overflow: scroll
slots:
default:
- component: widget:main_widget_Weather_Card
config:
bigCard: true
dateFormat: true
itemPrefix: OneCallAPIweatherandforecast_
locationTitle: =props.locationTitle
sunIndicator: true
visible: '=(!vars.objVar || ((vars.objVar.selectSection=="SECTION0") && !vars.objVar.selectThing)) ? true : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
for: sceneItem
groupItem: =props.scenesGroup
sourceType: itemsInGroup
slots:
default:
- component: widget:main_widget_Scene_Card
config:
scene: =loop.sceneItem.name
sceneName: =loop.sceneItem.label
visible: '=vars.objVar ? ((vars.objVar.selectSection + vars.objVar.selectThing)=="SECTION0Scenes") ? true : false : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: loop.equipmentItem.metadata.semantics.config.hasLocation == vars.room
for: equipmentItem
itemTags: Blinds
sourceType: itemsWithTags
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: '(loop.shutterItem.type=="Rollershutter") ? true : false'
for: shutterItem
groupItem: =loop.equipmentItem.name
sourceType: itemsInGroup
slots:
default:
- component: widget:main_widget_Rollershutter_Card
config:
RollerItem: =loop.shutterItem.name
visible: '=vars.objVar.selectThing=="Rollers" ? true : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: loop.equipmentItem.metadata.semantics.config.hasLocation == vars.room
for: equipmentItem
itemTags: Lightbulb
sourceType: itemsWithTags
slots:
default:
- component: widget:main_widget_Light_Card
config:
equipmentItem: =loop.equipmentItem.name
visible: '=vars.objVar.selectThing=="Lights" ? true : false'
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: loop.equipmentItem.metadata.semantics.config.hasLocation == vars.room
for: equipmentItem
itemTags: RadiatorControl
sourceType: itemsWithTags
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
for: tempItem
groupItem: =loop.equipmentItem.name
sourceType: itemsInGroup
slots:
default:
- component: widget:Temp_Control
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
visible: '=vars.objVar.selectThing=="Climate" ? true : false'
widgettrend: =loop.tempItem.name
- component: widget:main_widget_Security_Card
config:
securityGroup: =props.securityGroup
securityMode: =props.securityMode
visible: '=vars.objVar ? ((vars.objVar.selectSection + vars.objVar.selectThing)=="SECTION0Security") ? true : false : false'
- component: Label
config:
style:
flex: 1 1 auto
overflow-y: auto
position: relative
text: =vars.objVar.selectSection + vars.floor
visible: "=vars.objVar ? true : false"
- component: f7-block
config:
style:
flex: 0 0 auto
margin-bottom: -2em
overflow: scroll
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: green
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="Security" ? "#F8BB00" : "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" ? "#6A6A6A" : "#8C8C8C"'
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: textColor
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="Scenes" ? "#F8BB00" : "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" ? "#6A6A6A" : "#8C8C8C"'
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: textColor
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="Weather" ? "#F8BB00" : "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" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: Weather
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: HVAC
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="HVAC" ? true : false'
icon-f7: flame
iconColor: textColor
iconSize: 20
style:
--f7-button-bg-color: '=vars.objVar.selectThing=="HVAC" ? "#F8BB00" : "transparent"'
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="HVAC" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="HVAC" ? "#6A6A6A" : "#8C8C8C"'
font-size: 12px
height: auto
text: HVAC
- component: f7-block
config:
style:
background: =props.bnavColor
border-radius: 0px 0px 10px 10px
flex: 0 0 auto
margin-bottom: -2em
overflow: scroll
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? false : true : 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: Lights
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Lights" ? true : false'
icon-f7: lightbulb
iconColor: '=vars.objVar.selectThing=="Lights" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Lights" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Lights" ? "black" : "white"'
font-size: 12px
height: auto
text: Lights
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Climate
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Climate" ? true : false'
icon-f7: snow
iconColor: '=vars.objVar.selectThing=="Climate" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Climate" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Climate" ? "black" : "white"'
font-size: 12px
height: auto
text: Climate
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Rollers" ? true : false'
icon-f7: archivebox
iconColor: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Rollers" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
font-size: 12px
height: auto
text: Rollers
- 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
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
looks good for me with one addition/question: Why not use an “All Room” for Rooms menu like for the Floors menu?
Cause I voted against „all“ option on both, floor and room.
That would be really complex, error prone and perhaps a really long list of information to show.
Approved with the exception of implementing „All“ menu entries.
it’s also fine for me. Let’s do it without “all” for both sections and if someone wants to add it in future he’s free to so.
I think we have to cut out a bit of complexity and therefore you are absolutely right with your vote!
This is what hmerk was referring to when he said that it has to do with whether vars.objVar
exists. Right now, before you press any button, vars.ObjVar
equals undefined
, so there’s no way that vars.objVar.selectSection
can equal "SECTION" + loop.baseMenu_idx
. If you want the expression to be responsive before you press a button then you have to account for the undefined state of vars.objVar
.
Usually this is most easily done with a simple OR statement because undefined
will be interpreted as a false value. Because we’re looking at the property of an object it’s usually best to test each level as we go. So if you have:
((var.objVar && vars.objVar.selectSection) || "Section0")
first the parser will look at var.objVar
if that doesn’t exist, then already the innner AND statement is false and the parser moves to the second part of the outer OR statement. "Section0"
is a non-zero non-false value (therefore it counts as true) so the OR statement returns that value. The same line of reasoning applies if vars.objVar
does exist but vars.objVar.selectSection
does not. However, if vars.objVar
does exist and vars.objVar.selectSection
also exists then the inner AND statement is true and the most recently evaluated value (in this case vars.objVar.selectSection
) is returned.
Ok, so i will try to bring all the latest changes/improvements together tonight and start with the information for the floors menu.
I understand what you mean and what you say - but not how to do it
I use this code:
class: '=((vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx) || "Section0") ? "selected_menu_item" : "unselected_menu_item"'
this should set it to “Section0” or am I wrong? Or do I use it completely wrong (did not understand how to check objvar)… Is class
at all the right place for this?
Hey @hmerk cause of all the progress I totally forgot this issue.
I created a non semantic group and assigned in a first step a light.
The non-semantic group is shown in the rooms but the lights does not appear. My config is:
Seems I missed something for the light - but what?
class
is the correct place, you are making a jump in reasoning that most computer languages don’t/can’t. While there are some cases where it is OK for a value to be undefined
or whatever the language equivalent is, trying to then do something more with that value is an immediate issue because it is “undefined” so the language has no context to work with. If I ask you what a “procklenard” is, you would say “there’s no such thing” which is fine answer. If I ask you “what do you get when you double a procklenard” your only possible answer is “I can’t even begin to tell you, because I don’t know what a procklenard is”.
If vars.objVar
doesn’t exist, the parser is happy to tell you that. But if you ask it what is the selectSection
property of something that doesn’t exist, it’s only possible answer is, “I can’t even begin to tell you, because I don’t know what vars.objVar
is”. In computer speak, “I can’t even begin to tell you…” is just error
.
This is what I meant by this line. If there’s ever a chance that an expression with vars.objVar
is going to be needed before vars.objVar
exists (which of course there is), then we can’t try to use that value for anything else (getting a property or it, or adding it to something else, for example) until we give the expression parser a way to fall-back to a sensible value. That’s what those &&
and ||
statements do.
The other piece to this that I didn’t explicitly describe is that the &&
and ||
statements do not just return true
or false
they return whatever the most recent value they evaluated is as soon as they know whether the logic is true or false. For example (2 == 3 || "orange")
first checks 2 == 3
, well, this is obviously false, but since the OR statement could still be true it has to check the second value. So it then evaluates "orange"
. Well, that is a value that exists, is not 0
and is not false
so as far as the parser is concerned that is true and the OR statement returns the last thing it evaluated: "orange"
.
So you want a statement that returns vars.objVar.selectSection
, but only if vars.objVar
and vars.objVar.selectSection
exist. One way to do that would be:
(vars.objVar && vars.objVar.selectSection)
but then you want the expression to return "Section0"
if any of that up above equals false:
((vars.objVar && vars.objVar.selectSection) || "Section0")
now you’re ready to test if the result of that actually equals “Section” plus whichever button you are on:
((vars.objVar && vars.objVar.selectSection) || "Section0") == "Section" + loop.baseMenu_idx
Finally you can use that test as the condition for the ternary statement that decides which class to give your button:
class: '=(((vars.objVar && vars.objVar.selectSection) || "Section0") == "Section" + loop.baseMenu_idx) ? "selected_menu_item" : "unselected_menu_item"'
Lights should be lightbulb as equipment and member of an equipment group:)
@Team, as promised, I took some time and have a poc ready to test.
This poc includes the following changes:
- Removed default textColor value from props
- Implemented @Nic0205’s stylesheet for text coloring and formatting
- Changed --menu-text-color to set to props.textColor or to black/white depending on themeOptions (light/dark)
- Cut off the middle information block and created 3 new cards : Home, Floor and Room
- Changed bottom tabs entries to follow @Dimitris design
The code can be found here
Please test and report back.
Sorry, my bad. It does not work with non semantic groups as we need the tag “Lightbulb” to identify the lights. So you will definitely need one equipment for each light in the room.
Good morning!
@hmerk thanks for tour great job!
I’ve just tested new widgets,and i found some strange layout issues. Explained below.
Following devices widgets are ready to be published,reflecting Dimitri style.
I have also hvac widget ready…
@rubenfuser @All I want to ask for a big favor. Since we are develop the “white theme”, is it possible to post screenshots with that in mind? Also, try to stick as more as you can with the reference design both for Nav/tab and widgets. That would help me a lot to fine tune the final appearance and improve the UX.
Widgetsv4.pdf (401.5 KB)
Many thanks!
@Dimitris I have some concerns about your design for the security and HVAC widgets.
-
Security
As said before, items should not be presented as toggles, as you should not be able to change single items here. I have implemented a new feature which is not documented by now. Configuring securityGroup, securityMode and referencePIN items for main_widget, you now can change the security mode by pressing one of the three shields. A popup will be shown for entering the PIN. Only correct PIN will change the security mode. -
HVAC
I think we need to deploy different versions of the HVAC widget, as there are so many different heating systems on the market, that makes it nearly impossible to cover all in one widget. In Germany, most common are radiator controls, which only use targetTemperature, ambientTemperature and valvePosition. But let me think a bit more about it. It is already not that easy to configure a widget with two different temperature items automatically. We might need to add two nee tags to the modell, ambient and target….
One more comment to navbar/tabs. @rubenfuser was showing screenshots from last nights poc, which is not finished and has not all styles applied. Therefore those parts will still look a bit different from what the final result will/shall be