AFAIK you should not use spaces in location
- component: widget:widget_HeatingCSS_2.0.0
config:
location: NoSpacesHere
...
EDIT: seems others stumbled on the same Heating widget - #41 by RowanS
AFAIK you should not use spaces in location
- component: widget:widget_HeatingCSS_2.0.0
config:
location: NoSpacesHere
...
EDIT: seems others stumbled on the same Heating widget - #41 by RowanS
Hi all,
I’ve stumbled upon this heating widget and I gotta admit that it is a real beauty folks. Thank you Nico for putting it together.
I would like to use it for my own application, but I’ve trouble understanding the concept behind.
Currently I turn on/off the heater with an USB relay manually.
The way it is done in OH:
1 item:
2 rules based on item state:
relay on (runs exec command to activate USB relay)
relay off (runs different exec command to deactive the relay)
Currently it is independent of any temperature, however I’ve recently got a z-wave sensor to measure °C in the house, so I would like to upgrade the setup.
As I undrestand the “Setpoint item” is an item for your thermostat with another °C reading?
Would it be possible to program the widget to have a set temperature (manually set) then when it is reached it triggers relay off, and when temperature drops below the set, it triggers relay on rule?
Or for this to achieve I should start with a new rule or new widget?
Thank you for your kind support!
Cheers.
BUMP - any help would be really appreciated
I have the same issue using a Hue sensor. On line 972 you can preserve the original intent of displaying a number rounded to 1 decimal place by just adding .split(' ')[0]
after .state
to give:
text: =Number(items[props.currentPointItem].state.split(' ')[0]).toFixed(1)
I’m figuring out how to do something similar to you at the moment - separate sensor and relay to turn on and off heating.
Setpoint in this context is just a number item that you supply to the heating widget configuration - you may want to initialise it via a rule or with a standard widget on a page for testing.
The heating widget just gives you the UI and allows you to change the setpoint or mode (on/off/etc). You need to update your rules to test for current temperature against setpoint and turn your relay on or off accordingly. Just work with the items that you specify to the widget.
Hi joh!
This morning I could finally solve the case. I’ve used and tweaked the rule from here:
https://community.openhab.org/t/my-central-heating-solution-using-thermal-actuators/41320
Then I’ve assigned the Setpoint item in the widget. It works just fine so far.
Cheers!
Hi.
I recently installed the heating widget 2.0.0 using OH 3.1. I can set the temp of my heater, display the actual temp but cannot see nor set the mode.
The item works (verified) and I entered auto,manual,off as the modes for my heater.
What should I expect to see in the widget?
When I press the ‘hand’ in the widget, nothing happens.
Any idea of what can be wrong?
-ben
Problem solved, there were spaces in the location property, after removing them all works great.
Tnx @crnjan !
Do you think there is a possibility to integrate an schedule? Or do you know such an Widget?
I’m pretty new to the widgets on OH3, and this is really nice one for Heating thermostat, but I tried to edit to allow me to add my AC unit. we get pretty hot down here in the South. (US) any chance you can add a coolset point to this? I failed multiple times…LOL I need Heat and Cool
do u have a Nest Thermostat?i have the same problems with you…
Certainly do, I’ve made updates to the widget for it to display correctly.
Happy to share the updated code if you like?
sure mate thank you very much
Hello, I have a Nest thermostat and having the same issue. Would you be kind enough to share the updated code as well?
Mind sharing the code??
how can i make the widget to move the setpoint by 1C and not 0.5C that it is now?
Any ideas on that?i searched the widget’s code but couldnt understand what need to be changed…
Hello Constantinos,
i quickly scanned the code of Version 2.0.0 and found the following line:
actionCommand: “=Number(items[props.setPointItem].state.split(’ ‘)[0]) > Number(props.minTemp) ? Number(items[props.setPointItem].state.split(’ ')[0]) - 0.5 : ‘’”
See the- 0.5
? Same is true for the button configured in a similar line below with +0.5
It simply decreases/increases the current setpoint value by 0.5 degree if it has not already reached the minimum/maximum.
This should answer your question.
Regards
Thomas
i have a Nest thermostat,the temperature item is a Number:Temperature and in the center of the widget it shows NaN.
If i change the temperature item to just a Number then the widget is showing the Number allright…How can i fix that?
Many thanks for this great widget. I’m also having this same issue with rounding the setpoint value. I’m using %.1f °C pattern in the stateDescription of this item. I tried to use .displayState
instead of .state
but I managed to screw up the widget so I wonder where to make this change.
Another question, where can I change the size of the text for the humidity (38.80%)?
My code for the widget is:
uid: widget_HeatingCSS_2.0.0
tags: []
props:
parameters:
- context: item
description: Item to control
label: Setpoint Item
name: setPointItem
required: true
type: TEXT
groupName: mainItems
- context: item
label: Item for current temperature
name: currentPointItem
required: true
type: TEXT
groupName: mainItems
- context: item
description: Humidity Item [Number-Item]
label: Humidity Item
name: humItem
required: false
type: TEXT
groupName: mainItems
- description: eg. living room
label: location and widget identifier
name: location
required: true
type: TEXT
groupName: generalSettings
- description: Minimum value
label: minTemp
name: minTemp
required: true
type: TEXT
groupName: generalSettings
- description: Maximum value
label: maxTemp
name: maxTemp
required: true
groupName: generalSettings
- description: Visual size of the control in px (default 400px), without a size the design is responsive
label: size [px]
name: size
required: false
type: TEXT
groupName: generalSettings
- description: Control item unit eg °C
label: unit
name: unit
required: false
type: TEXT
groupName: generalSettings
advanced: true
- context: item
description: Heating Mode Item [String-Item]
label: Heating Mode Item
name: heatingModeItem
required: false
type: TEXT
groupName: extensionItems
advanced: true
- description: Heating mode strings as array eg. AUTO,MANU,OFF. The string will be send to the Heating-Mode-Item [String-Item]
label: Heating Mode Array
name: heatingModeArray
required: false
type: TEXT
groupName: extensionItems
advanced: true
- context: item
description: Example Mode Item [String-Item] (eg. State of heating valve)
label: Example Mode Item
name: exampleModeItem
required: false
type: TEXT
groupName: extensionItems
advanced: true
- description: Example Mode Strings as Array eg. OFF,ON,BOOST. The string will be send to the Example-Mode-Item [String-Item]
label: Example Mode Array
name: exampleModeArray
required: false
type: TEXT
groupName: extensionItems
advanced: true
- context: item
description: Valve/Alarm Item [Switch-Item] (eg. State of heating valve) for Animation in the center of the widget
label: Valve Item
name: valveItem
required: false
type: TEXT
groupName: extensionItems
advanced: true
- context: item
description: Extension Item 1 eg. Battery-State [Number-Item]
label: Extension Item 1
name: extensionItem1
required: false
type: TEXT
groupName: extensionItems
advanced: true
- description: Choose the F7-Icons for the Extension Item 1 as Array. -> <battery_100,battery_25,battery_0>. 1st Icon = Value > 75, 2nd Icon = Value > 25, 3th Icon = Value < 25
label: Extension Item 1 F7-Icon
name: extensionItem1Icon
required: false
type: TEXT
groupName: extensionItems
advanced: true
- context: item
description: Extension Item 2 eg. Battery-State [Number-Item]
label: Extension Item 2
name: extensionItem2
required: false
type: TEXT
groupName: extensionItems
advanced: true
- description: Choose the F7-Icons for the Extension Item 2 F7-Icon as Array. -> <battery_100,battery_25,battery_0>. 1st Icon = Value > 75, 2nd Icon = Value > 25, 3th Icon = Value < 25
label: F7-Icon for the Extension Item 2
name: extensionItem2Icon
required: false
type: TEXT
groupName: extensionItems
advanced: true
- description: URL or path to a Image (if you use a local img eg. -> http://local-IP-Adress:8080/static/folder/img.svg )
label: URL or path to image
name: imgUrl
required: false
type: TEXT
groupName: moreDesign
advanced: true
- description: eg. default 1em
label: Custom font-size current&set-point marker
name: fontSizeMarker
required: false
type: TEXT
groupName: fonts
advanced: true
- description: eg. default 2em
label: Custom font-Size center
name: fontSizeCenter
required: false
type: TEXT
groupName: fonts
advanced: true
- description: default 1em for eg. Living Room
label: Custom font-size location label
name: fontSizeLocation
required: false
type: TEXT
groupName: fonts
advanced: true
- description: default eg. 1.8em
label: Custom font-Size buttons
name: fontSizeButtons
required: false
type: TEXT
groupName: fonts
advanced: true
- description: default 1em for Heating-Label in bottom of the widget
label: Custom font-Size footer
name: fontSizeFooter
required: false
type: TEXT
groupName: fonts
advanced: true
- label: Main-Color Thermostat
name: colorThermostat
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color control ring
name: colorControlRing
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color buttons
name: colorButton
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color center
name: colorCenter
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color Typo
name: colorTypo
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color setPoint Marker
name: colorSetMarker
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color currentPoint Marker
name: colorCurrentMarker
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color bar linear gradient startPoint
name: colorBarStartPoint
required: false
type: TEXT
groupName: colors
advanced: true
- label: Color bar linear gradient endPoint
name: colorBarEndPoint
required: false
type: TEXT
groupName: colors
advanced: true
- description: Control if the Chart is visible
label: Chart Swtich
name: chartSwitch
required: false
type: BOOLEAN
groupName: chartSettings
- description: currently not possible -> The minimun value of axis. (eg. 10.5)
label: yAxis min
name: yAxisMin
required: false
type: TEXT
groupName: chartSettings
advanced: true
- description: currently not possible -> The maximum value of axis. (eg. 30.5)
label: yAxis max
name: yAxisMax
required: false
type: TEXT
groupName: chartSettings
advanced: true
parameterGroups:
- name: mainItems
label: Main Items (setpoint-temperature, current temperature, humidity)
- name: advancedItems
label: Advanced Items (Battery-State, ...)
- name: generalSettings
label: General Settings
- name: extensionItems
label: Extension Items
- name: moreDesign
label: More Design Options
- name: colors
label: Color Settings
- name: fonts
label: Font Settings
- name: chartSettings
label: Chart Settings
timestamp: Apr 14, 2021, 9:31:45 PM
component: f7-card
config:
title: "=(props.location) ? 'Klima ' + props.location : ''"
stylesheet: >
.mylink {
#background-color: blue !important;
animation-name: example;
animation-duration: 4s;
} .mylink#####:hover {
text-decoration: underline !important;
transform: scale(1.5);
transition: 0.3s all;
}
@keyframes example {
0% {background-color: red;}
25% {background-color: yellow;}
50% {background-color: blue;}
100% {background-color: green;}
}
.thermostat {
flex-shrink: 0;
--f7-block-margin-vertical: 0px;
--f7-block-padding-vertical: 0px;
--f7-block-padding-horizontal: 0px;
padding-left: 0px;
border-radius: 50%;
box-sizing: content-box;
border: 2px solid rgb(64, 60, 77);
}
.thermostat .bar {
margin-top: 0px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
} .thermostat .bar .inner_bar {
margin-top: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 100%;
z-index: 4 !important;
} .thermostat .bar .inner_bar .block {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
left: 50%;
transform: translate(-50%);
}
slots:
default:
- component: f7-card-content
slots:
default:
- component: f7-row
config:
resizableFixed: true
resizable-absolute: true
class:
- justify-content-center
slots:
default:
- component: f7-block
config:
class: thermostat
style:
padding-top: "=props.size ? props.size + 'px': '100%'"
width: "=props.size ? Number(props.size)+'px' : '100%'"
background: "=props.colorThermostat ? props.colorThermostat : 'var(--f7-toggle-inactive-color)'"
slots:
default:
- component: f7-block
config:
class: bar
style:
width: "=props.size ? (Number(props.size)*0.89) +'px' : '89%'"
height: "=props.size ? (Number(props.size)*0.89) +'px' : '89%'"
slots:
default:
- component: f7-block
config:
class: inner_bar
style:
width: "=props.size ? (Number(props.size)*0.86) +'px' : '97%'"
height: "=props.size ? (Number(props.size)*0.86) +'px' : '97%'"
background-color: "=props.colorThermostat ? props.colorThermostat : 'var(--f7-toggle-inactive-color)'"
slots:
default:
- component: f7-block
config:
style:
background: "='conic-gradient(transparent 0deg 160deg, ' + (props.colorThermostat ? props.colorThermostat : 'var(--f7-toggle-inactive-color)') + ' 160deg 200deg, transparent 200deg 360deg)'"
bottom: "=props.size ? '-7px' : '-7px'"
- component: f7-block
config:
class: hold left
style:
margin-top: 0px
position: absolute
width: 100%
height: 100%
clip-path: "=props.size ? 'inset(0px 0px 0px ' + (Number(props.size)*0.89/2) + 'px)' : 'inset(0% 0% 0% 50%)'"
border-radius: 100%
background-color: rgb(58, 55, 73)
slots:
default:
- component: f7-block
config:
class: fill fill1
style:
margin-top: 0px
position: absolute
width: 100%
height: 100%
border-radius: 100%
clip-path: "=props.size ? 'inset(0px ' + (Number(props.size)*0.89/2) + 'px 0px 0px)' : 'inset(0% 50% 0% 0%)'"
background: "=props.colorBarStartPoint && props.colorBarEndPoint ? '-webkit-linear-gradient(top, ' + props.colorBarEndPoint + ' 20%,' + props.colorBarEndPoint + ' 100%)' : '-webkit-linear-gradient(top, rgb(255, 73, 0) 20%,rgb(255, 73, 0) 100%)'"
z-index: 1 !important
transition: transform 0.6s
transform: "=(items[props.setPointItem].state.split(' ')[0] >= (((Number(props.maxTemp) - Number(props.minTemp)) / 2) + Number(props.minTemp)) && items[props.setPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : (items[props.setPointItem].state.split(' ')[0] > Number(props.maxTemp)) ? 'rotate(180deg)' : '')"
- component: f7-block
config:
class: hold right
style:
margin-top: 0px
position: absolute
width: 100%
height: 100%
clip-path: "=props.size ? 'inset(0px 0px 0px ' + (Number(props.size)*0.89/2) + 'px)' : 'inset(0% 0% 0% 50%)'"
border-radius: 100%
background-color: rgb(58, 55, 73)
z-index: 3 !important
transform: rotate(180deg)
slots:
default:
- component: f7-block
config:
class: fill
style:
margin-top: 0px
position: absolute
width: 100%
height: 100%
border-radius: 100%
z-index: 3 !important
animation: right 1s linear both
transition: transform 0.6s
- component: f7-block
config:
class: fill fill2
style:
position: absolute
margin-top: 0px
width: 100%
height: 100%
border-radius: 50%
z-index: 3 !important
clip-path: "=props.size ? 'inset(0px '+ (Number(props.size)*0.89/2) + 'px 0px 0px)' : 'inset(0% 50% 0% 0%)'"
background: "=props.colorBarStartPoint && props.colorBarEndPoint ? '-webkit-linear-gradient(top, ' + props.colorBarEndPoint + ' 40%,' + props.colorBarStartPoint + ' 100%)' : '-webkit-linear-gradient(top, rgb(255, 73, 0) 40%,rgb(255, 158, 35) 100%)'"
transform: "=(items[props.setPointItem].state.split(' ')[0] <= (((Number(props.maxTemp) - Number(props.minTemp)) / 2) + Number(props.minTemp)) && items[props.setPointItem].state.split(' ')[0] >= Number(props.minTemp) ? 'rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))+20)+'deg)' : (items[props.setPointItem].state.split(' ')[0] > (((Number(props.maxTemp) - Number(props.minTemp)) / 2) + Number(props.minTemp))) ? 'rotate(180deg)' : '')"
- component: f7-block
config:
class: span
style:
margin-top: 0px
width: "=props.size ? (Number(props.size)*0.89) +'px' : '100%'"
font-weight: "=props.size ? (Number(props.size)*2) +'px' : 'calc(var(--f7-list-item-title-font-weight)*2)'"
position: absolute
bottom: 0px
text-align: center
text-transform: uppercase
font-size: "=props.fontSizeFooter ? props.fontSizeFooter : '1em'"
color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
z-index: 99 !important
slots:
default:
- component: Label
config:
text: Heating
- component: f7-block
config:
class: shadow
style:
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: "=(items[props.setPointItem].state.split(' ')[0] >= Number(props.minTemp) && items[props.setPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'translate(-50%, -50%) rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : 'translate(-50%, -50%) rotate(0deg)')"
width: "=props.size ? (Number(props.size)*0.0625) +'px' : '6.25%'"
height: 86%
text-align: center
transition: 0.7s ease
animation: shadow 1.4s ease-out both
slots:
default:
- component: f7-block
config:
class: shadow-cube
style:
margin-top: 0px
position: absolute
top: 0
width: "=props.size ? (Number(props.size)*0.0625) +'px' : '100%'"
height: 0px
box-shadow: "=props.size ? '0 0 ' + (Number(props.size)*0.1125) +'px ' + (Number(props.size)*0.0325) + 'px ' + (props.colorSetMarker ? props.colorSetMarker : 'rgba(255, 158, 35, 0.5)'): '0 0 45px 13px rgba(255, 158, 35, 0.5)'"
- component: f7-block
config:
class: markerContainer
style:
pointer-events: none
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: "=(items[props.currentPointItem].state.split(' ')[0] >= Number(props.minTemp) && items[props.currentPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'translate(-50%, -50%) rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.currentPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : 'translate(-50%, -50%) rotate(0deg)')"
width: "=props.size ? (Number(props.size)*0.1) +'px' : '10%'"
height: 100%
text-align: center
transition: 0.7s ease
opacity: 1
z-index: 99 !important
slots:
default:
- component: f7-block
config:
class: markerCurrent
style:
margin-top: 0px
width: "=props.size ? (Number(props.size)*0.1) +'px' : '100%'"
height: "=props.size ? (Number(props.size)*0.1) +'px' : ''"
padding-top: "=props.size ? '' : '100%'"
background: "=props.colorCurrentMarker ? props.colorCurrentMarker : 'rgb(33, 150, 243)'"
position: absolute
transform: translate(-50%,-50%) rotate(45deg)
left: 50%
top: "=props.size ? (Number(props.size)*0.14) +'px' : '15%'"
border-radius: 0% 50% 50% 50%
box-shadow: 0 0 5px 1px rgb(48, 46, 56)
slots:
default:
- component: f7-block
config:
class: number
style:
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%) rotate(-45deg)
text-align: center
slots:
default:
- component: Label
config:
text: =items[props.currentPointItem].state.split(' ')[0]
style:
font-size: "=props.fontSizeMarker ? props.fontSizeMarker : '1em'"
color: white
font-weight: bold
- component: f7-block
config:
class: markerContainer
style:
pointer-events: none
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: "=(items[props.setPointItem].state.split(' ')[0] >= Number(props.minTemp) && items[props.setPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'translate(-50%, -50%) rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : 'translate(-50%, -50%) rotate(0deg)')"
width: "=props.size ? (Number(props.size)*0.1) +'px' : '10%'"
height: 100%
text-align: center
transition: 0.7s ease
opacity: 1
z-index: 99 !important
slots:
default:
- component: f7-block
config:
class: markerSet
style:
margin-top: 0px
width: "=props.size ? (Number(props.size)*0.1) +'px' : '100%'"
height: "=props.size ? (Number(props.size)*0.1) +'px' : ''"
padding-top: "=props.size ? '' : '100%'"
background: "=props.colorSetMarker ? props.colorSetMarker : 'rgb(230, 74, 25)'"
position: absolute
transform: translate(-50%,-50%) rotate(-45deg)
left: 50%
top: "=props.size ? (Number(props.size)*Number(-0.0125)) +'px': '-2%'"
border-radius: 50% 50% 50% 0
box-shadow: 0 0 5px 1px rgb(48, 46, 56)
z-index: 100 !important
slots:
default:
- component: f7-block
config:
class: number
style:
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%) rotate(45deg)
text-align: center
slots:
default:
- component: Label
config:
text: =items[props.setPointItem].state.split(' ')[0]
style:
font-size: "=props.fontSizeMarker ? props.fontSizeMarker : '1em'"
color: white
font-weight: bold
- component: f7-block
config:
class: center
style:
margin-top: 0px
position: absolute
width: "=props.size ? (Number(props.size)*0.65) +'px' : '65%'"
height: "=props.size ? (Number(props.size)*0.65) +'px' : '65%'"
background: "=props.colorControlRing ? props.colorControlRing : 'rgb(227, 228, 237)'"
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
box-shadow: 0px 15px 35px 11px rgba(46, 44, 58,0.60)
slots:
default:
- component: f7-swiper
config:
pagination: true
scrollbar: false
params:
slidesPerView: 1
direction: horizontal
mousewheel: true
style:
width: 100%
height: 100%
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
slots:
default:
- component: f7-swiper-slide
config:
style:
width: 100%
height: 100%
slots:
default:
- component: f7-block
config:
class: page
style:
background: transparent
margin-top: 0px
position: absolute
width: 100%
height: 100%
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
slots:
default:
- component: f7-block
config:
class: buttonContainer
style:
display: "=props.heatingModeItem ? '' : 'none'"
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: "=props.exampleModeItem ? 'translate(-50%, -50%) rotate(30deg)' : 'translate(-50%, -50%)'"
width: "=props.size ? (Number(props.size)*0.15) +'px' : '15%'"
height: 100%
text-align: center
transition: 0.7s ease
opacity: 1
z-index: 99 !important
slots:
default:
- component: oh-button
config:
popoverOpen: ='.' + props.location + '.popoverHeatingMode'
style:
width: 100%
height: 20%
position: absolute
bottom: 0%
left: 50%
transform: translate(-50%)
color: "=props.colorButton ? props.colorButton + ' !important': ''"
slots:
default:
- component: f7-icon
config:
f7: "=props.heatingModeItem ? (items[props.heatingModeItem].state == props.heatingModeArray.split(',')[0] ? 'hand_raised' : items[props.heatingModeItem].state == props.heatingModeArray.split(',')[1] ? 'arrow_2_squarepath' : items[props.heatingModeItem].state == props.heatingModeArray.split(',')[2] ? 'airplane' : 'thermometer') : ''"
style:
font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
position: absolute
transform: translate(-50%, -50%)
top: 50%
margin-top: auto
- component: f7-popover
config:
class: =props.location + ' popoverHeatingMode'
slots:
default:
- component: f7-card
config:
noShadow: true
class:
- popover-close
action: variable
actionVariable: myVar
clearVariable: true
actionVariableValue: success
slots:
default:
- component: f7-row
config: {}
slots:
default:
- component: f7-col
slots:
default:
- component: oh-repeater
config:
for: buttonlabel
in: =props.heatingModeArray.split(",")
containerStyle:
width: 100%
slots:
default:
- component: oh-button
config:
color: "=props.colorButton ? props.colorButton : ''"
class: margin
text: =loop.buttonlabel
outline: true
action: command
active: "=props.heatingModeItem ? (items[props.heatingModeItem].state === loop.buttonlabel ? true : false) : ''"
actionCommand: =loop.buttonlabel
actionItem: "=props.heatingModeItem ? props.heatingModeItem : ''"
- component: f7-block
config:
class: buttonContainer
style:
display: "=props.exampleModeItem ? '' : 'none'"
margin-top: 0px
position: absolute
top: 50%
left: 50%
transform: "=props.heatingModeItem ? 'translate(-50%, -50%) rotate(-30deg)' : 'translate(-50%, -50%)'"
width: "=props.size ? (Number(props.size)*0.15) +'px' : '15%'"
height: 100%
text-align: center
transition: 0.7s ease
opacity: 1
z-index: 99 !important
slots:
default:
- component: oh-button
config:
popoverOpen: ='.' + props.location + '.popoverExampleMode'
style:
width: 100%
height: 20%
position: absolute
bottom: 0%
left: 50%
transform: translate(-50%)
color: "=props.colorButton ? props.colorButton + ' !important': ''"
slots:
default:
- component: f7-icon
config:
f7: wrench
style:
font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
position: absolute
transform: translate(-50%, -50%)
top: 50%
margin-top: auto
- component: f7-popover
config:
class: =props.location + ' popoverExampleMode'
slots:
default:
- component: f7-card
config:
noShadow: true
class:
- popover-close
action: variable
actionVariable: myVar
clearVariable: true
actionVariableValue: success
slots:
default:
- component: f7-row
config: {}
slots:
default:
- component: f7-col
slots:
default:
- component: oh-repeater
config:
for: buttonlabel
in: =props.exampleModeArray.split(",")
containerStyle:
width: 100%
slots:
default:
- component: oh-button
config:
color: "=props.colorButton ? props.colorButton : ''"
class: margin
text: =loop.buttonlabel
outline: true
action: command
active: "=props.exampleModeItem ? (items[props.exampleModeItem].state === loop.buttonlabel ? true : false) : ''"
actionCommand: =loop.buttonlabel
actionItem: "=props.exampleModeItem ? props.exampleModeItem : ''"
- component: oh-button
config:
style:
width: 30%
height: 50%
position: absolute
margin-top: 0px
top: 50%
left: 10%
transform: translate(-50%, -50%)
color: "=props.colorButton ? props.colorButton : ''"
action: command
actionItem: =props.setPointItem
actionCommand: "=Number(items[props.setPointItem].state.split(' ')[0]) > Number(props.minTemp) ? Number(items[props.setPointItem].state.split(' ')[0]) - 0.1 : ''"
slots:
default:
- component: f7-icon
config:
style:
font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
position: absolute
transform: translate(-50%, -50%)
top: 50%
margin-top: auto
f7: arrow_turn_left_down
- component: oh-button
config:
style:
width: 30%
height: 50%
position: relative
margin-top: 0px
top: 50%
left: 90%
transform: translate(-50%, -50%)
color: "=props.colorButton ? props.colorButton : ''"
action: command
actionItem: =props.setPointItem
actionCommand: "=Number(items[props.setPointItem].state.split(' ')[0]) < Number(props.maxTemp) ? Number(items[props.setPointItem].state.split(' ')[0]) + 0.1 : ''"
slots:
default:
- component: f7-icon
config:
style:
font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
position: absolute
transform: translate(-50%, -50%)
top: 50%
margin-top: auto
f7: arrow_turn_right_up
- component: f7-block
config:
class: valveAnimation
style:
z-index: -100 !important
pointer-events: none
display: "=(props.valveItem && items[props.valveItem].state == 'ON' )? '' : 'none'"
background: "=props.colorSetMarker ? 'radial-gradient(' + props.colorSetMarker +' 30%, transparent 50%)' : 'radial-gradient(var(--f7-theme-color) 30%, transparent 50%)'"
margin-top: 0px
position: absolute
transform: translate(-50%, -50%)
width: 100%
height: 100%
top: 50%
left: 50%
border-radius: 50%
animation: skeleton-effect-fade 2s linear infinite
- component: f7-block
config:
class: small
style:
z-index: 100 !important
margin-top: 0px
position: absolute
width: "=props.size ? (Number(props.size)*0.375) +'px' : '57.6%'"
height: "=props.size ? (Number(props.size)*0.375) +'px' : '57.6%'"
background: "=props.colorCenter ? props.colorCenter : 'rgb(248, 249, 250)'"
text-align: center
animation: bound-in-small 0.6s ease forwards
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
box-shadow: 0px 5px 10px 5px rgba(96, 93, 111,0.19)
slots:
default:
- component: f7-block
config:
class: heat
style:
font-size: "=props.fontSizeLocation ? props.fontSizeLocation : '1em'"
color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
font-weight: 300
transform: translate(-50%)
left: 50%
margin-top: 10%
slots:
default:
- component: Label
config:
text: =props.location
- component: f7-swiper
config:
scrollbar: false
params:
autoplay:
delay: 1500
disableOnInteraction: false
slidesPerView: 1
direction: vertical
mousewheel: true
style:
width: 100%
height: 100%
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
slots:
default:
- component: f7-swiper-slide
config:
style:
display: "=props.humItem ? '' : 'none'"
slots:
default:
- component: f7-block
config:
class: heat
style:
margin-top: 0
font-size: "=props.fontSizeCenter ? props.fontSizeCenter : '2em'"
color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
font-weight: 300
position: absolute
transform: translate(-50%,-50%)
top: 50%
left: 50%
display: flex
slots:
default:
- component: Label
config:
text: =items[props.humItem].state
- component: Label
config:
text: =items[props.humItem].displayState.split(' ')[1]
style:
font-size: "=props.fontSizeCenter ? 'calc(' + props.fontSizeCenter + ' * 0.2 )' : '0.6em'"
vertical-align: top
- component: f7-swiper-slide
config:
style:
display: "=props.currentPointItem ? '' : 'none'"
slots:
default:
- component: f7-block
config:
class: heat
style:
margin-top: 0
font-size: "=props.fontSizeCenter ? props.fontSizeCenter : '2em'"
color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
font-weight: 300
position: absolute
transform: translate(-50%,-50%)
top: 50%
left: 50%
display: flex
slots:
default:
- component: Label
config:
text: =Number(items[props.currentPointItem].state).toFixed(1)
- component: Label
config:
text: "=props.unit ? props.unit : items[props.currentPointItem].displayState.split(' ')[1]"
style:
font-size: "=props.fontSizeCenter ? 'calc(' + props.fontSizeCenter + ' * 0.2 )' : '0.6em'"
vertical-align: top
- component: oh-image
config:
url: "=props.imgUrl ? props.imgUrl : 'https://community-openhab-org.s3-eu-central-1.amazonaws.com/original/2X/7/7d388a86c95471f89b1bb911d96d7609a3e3a059.svg'"
style:
position: absolute
transform: translate(-50%)
left: 50%
bottom: 5%
width: 40%
- component: f7-swiper-slide
config:
style:
width: 100%
height: 100%
display: "=props.chartSwitch ? '' : 'none'"
slots:
default:
- component: f7-block
config:
class: page
style:
background: transparent
margin-top: 0px
position: absolute
width: 100%
height: 100%
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
slots:
default:
- component: oh-chart
config:
height: 100%
periodVisible: false
period: 12h
slots:
title:
- component: oh-chart-title
config:
text: 12h
left: center
bottom: 10%
textStyle:
fontSize: 1em
fontWeight: normal
grid:
- component: oh-chart-grid
config:
show: true
borderWidth: 0
top: 20%
left: 15%
right: 15%
height: 60%
xAxis:
- component: oh-time-axis
config:
show: true
gridIndex: 0
name: Uhrzeit
boundaryGap: false
axisLine:
onZero: true
axisTick:
show: false
axisLabel:
show: false
axisPointer:
label:
show: false
yAxis:
- component: oh-value-axis
config:
show: false
gridIndex: 0
min: auto
max: auto
name: Temperatur
nameLocation: center
nameGap: 45
axisLabel:
formatter: "{value} °C"
series:
- component: oh-time-series
config:
data:
name: istTemp
name: Ist Temp. Indoor
gridIndex: 0
xAxisIndex: 0
yAxisIndex: 0
type: line
item: "=props.currentPointItem ? props.currentPointItem : ''"
markPoint:
itemStyle:
color: "=props.colorCurrentMarker ? props.colorCurrentMarker : 'rgb(33, 150, 243)'"
data:
- type: max
name: Höchsttemperatur
- type: min
name: Tiefsttemperatur
smooth: true
lineStyle:
color: "=props.colorCurrentMarker ? props.colorCurrentMarker : 'rgb(33, 150, 243)'"
- component: oh-time-series
config:
name: Soll Temp. Indoor
gridIndex: 0
xAxisIndex: 0
yAxisIndex: 0
type: line
item: "=props.setPointItem ? props.setPointItem : ''"
step: end
lineStyle:
color: "=props.colorSetMarker ? props.colorSetMarker : 'rgb(230, 74, 25)'"
- component: f7-swiper-slide
config:
style:
width: 100%
height: 100%
display: "=(props.extensionItem1 || props.extensionItem2)? '' : 'none'"
slots:
default:
- component: f7-block
config:
class: page
style:
font-size: "=props.fontSizeLocation ? props.fontSizeLocation : '1em'"
background: transparent
margin-top: 0px
position: absolute
width: 100%
height: 100%
top: 50%
left: 50%
transform: translate(-50%, -50%)
border-radius: 50%
slots:
default:
- component: Label
config:
text: Extension Items
style:
margin-top: 5%
margin-bottom: 5%
text-align: center
- component: oh-repeater
config:
for: i
sourceType: range
rangeStart: "=props.extensionItem1 ? Number(1) : (!props.extensionItem1 && props.extensionItem2) ? Number(2) : ''"
rangeStop: "=(props.extensionItem1 && props.extensionItem2) ? Number(2) : (props.extensionItem1 && !props.extensionItem2) ? Number(1) : Number(2)"
slots:
default:
- component: f7-block
config:
style:
display: flex
flex-flow: row wrap
padding: 0 5% 0 5%
justify-content: space-evenly
align-items: center
slots:
default:
- component: f7-icon
config:
style:
min-width: 40px
line-height: 2
size: 2em
f7: '=props["extensionItem" + loop.i + "Icon"] ? ((Number.parseInt(items[props["extensionItem" + loop.i]].state) > 75) ? props["extensionItem" + loop.i + "Icon"].split(",")[0] : (Number.parseInt(items[props["extensionItem" + loop.i]].state) > 25) ? props["extensionItem" + loop.i + "Icon"].split(",")[1] : props["extensionItem" + loop.i + "Icon"].split(",")[2]) : "clear"'
color: '=(Number.parseInt(items[props["extensionItem" + loop.i]].state) > 75) ? "green" : (Number.parseInt(items[props["extensionItem" + loop.i]].state) > 25) ? "yellow" : "red"'
- component: f7-badge
config:
style:
line-height: 3
font-size: 1em
min-width: 30px
margin: 0 5px 0 5px
color: '=(Number.parseInt(items[props["extensionItem" + loop.i]].state) > 75) ? "green" : (Number.parseInt(items[props["extensionItem" + loop.i]].state) > 25) ? "yellow" : "red"'
slots:
default:
- component: Label
config:
text: =items[props["extensionItem" + loop.i]].displayState