Hello community! I’m trying to build a universal conditioner widget for every conditioner model.
this is the first release, so there could be some bugs or options to be fine tuned, so feel free to tell me what are issues you will find.
This widget looks into “Model” scheme, find some defined tags (described below) and automatically show/hide widget options.
This widget is the first of the package of widgets that i would like to distribute. My idea is to develope a set of universal widgets suitable for everyone and usable for different brand devices.
First thing to be done is to configure a Group and set it as “HVAC” in Semantic Class.
Then, you have to set:
Switch (for power on/off) as “Type” and “Semantic class” → Switch
Mode item as “Type” (String), “Semantic Class” (Control) and “Semantic Property” (Temperature);
Setpoint item, “Type” (Number:Temperature), “Semantic Class” (Setpoint) and “Semantic Property” (Temperature);
Temperature item as “Type” (Number:Temperature), “Semantic Class” (Measurement) and “Semantic Property” (Temperature);
Fan speed item as “Type” (String) and “Semantic Class” (Fan);
Fan direction item as “Type” (String) and “Semantic Class” (Tilt)
Maybe nothing too much different from the setup you already have.
Screenshots
Changelog
- Fixed displayState for Temperature and Setpoint items
Version 0.1
- initial release
Resources
uid: Universal_Conditioner_Card_Humidity
tags: []
props:
parameters:
- description: Small title on top of the card
label: Title
name: climaTitle
required: false
type: TEXT
- context: item
description: Conditioner Group Equipment
label: Conditioner Group Equipment
name: groupItem
required: true
type: TEXT
timestamp: Oct 13, 2022, 3:37:49 PM
component: f7-card
config:
noShadow: false
padding: false
style:
background: '=themeOptions.dark === "dark" ? "rgb(40, 40, 40)" : "rgb(240, 240, 240)"'
border-radius: var(--f7-card-expandable-border-radius)
box-shadow: 5px 5px 15px 1px rgba(0,0,0,0.3)
height: auto
margin-left: 5px
margin-right: 5px
padding: 0px
slots:
content:
- component: f7-card-content
config:
style:
height: auto
slots:
default:
- component: oh-icon
config:
icon: iconify:lucide:sun-snow
style:
color: rgb(33, 150, 243)
position: absolute
top: 23px
width: 40px
- component: f7-row
config:
style:
margin-left: 50px
margin-top: 0px
slots:
default:
- component: Label
config:
style:
color: '=themeOptions.dark === "dark" ? "white" : "black"'
font-size: 15px
font-weight: 500
text: =props.climaTitle
- component: oh-repeater
config:
filter: '((loop.switchItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.switchItem.type=="Switch")) ? true : false'
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Switch
for: switchItem
slots:
default:
- component: oh-toggle
config:
color: blue
item: =loop.switchItem.name
style:
position: absolute
right: 3%
top: 20px
--f7-toggle-height: 20px
--f7-toggle-inactive-color: red
--f7-toggle-width: 40px
z-index: 98
- component: f7-block
config:
style:
display: flex
justify-content: space-between
margin-top: 0px
margin-left: 35px
width: 150px
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: "(loop.tempItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
for: tempItem
itemTags: Measurement,Temperature
sourceType: itemsWithTags
slots:
default:
- component: f7-chip
config:
style:
color: '=items[loop.tempItem.name].state >= "21" ? "red" : items[loop.tempItem.name].state >= "19" ? "black" : "blue"'
background: rgb(240,240,240)
font-weight: 500
text: "=items[loop.tempItem.name].displayState ? items[loop.tempItem.name].displayState : items[loop.tempItem.name].state"
- component: oh-repeater
config:
filter: "(loop.setpointItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Setpoint,Temperature
for: setpointItem
slots:
default:
- component: f7-chip
config:
style:
background: transparent
color: rgb(33, 150, 243)
font-weight: 500
text: '=items[loop.setpointItem.name].displayState ? items[loop.setpointItem.name].displayState : items[loop.setpointItem.name].state == "UNDEF" ? "Not set" : items[loop.setpointItem.name].state'
- component: oh-repeater
config:
filter: "(loop.humidityItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Measurement,Humidity
for: humidityItem
slots:
default:
- component: f7-chip
config:
style:
background: transparent
color: rgb(33, 150, 243)
font-weight: 500
text: '=items[loop.humidityItem.name].displayState ? items[loop.humidityItem.name].displayState : items[loop.humidityItem.name].state ? items[loop.humidityItem.name].state : ""'
- component: f7-row
config:
style:
margin-top: 3%
slots:
default:
- component: f7-col
config:
style:
width: 73%
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: "(loop.tempItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
for: tempItem
itemTags: Measurement,Temperature
sourceType: itemsWithTags
slots:
default:
- component: oh-trend
config:
style:
--f7-theme-color-bg-color: transparent
background: var(--f7-theme-color-bg-color)
filter: opacity(100%)
margin-left: 40px
margin-top: 10%
height: 100%
z-index: 98
trendGradient: "=[themeOptions.dark === 'dark' ? 'rgb(33, 150, 243)' : ('red'),('white')]"
trendItem: =loop.tempItem.name
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
filter: "(loop.humidityItem.groupNames.indexOf(props.groupItem) >= 0) ? true : false"
for: humidityItem
itemTags: Measurement,Humidity
sourceType: itemsWithTags
slots:
default:
- component: oh-trend
config:
style:
--f7-theme-color-bg-color: transparent
background: var(--f7-theme-color-bg-color)
filter: opacity(100%)
margin-left: 40px
margin-top: 5px
z-index: 98
trendGradient:
- blue
- black
trendItem: =loop.humidityItem.name
- component: f7-col
config:
style:
width: 20px
slots:
default:
- component: oh-repeater
config:
filter: '((loop.switchItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.switchItem.type=="Switch")) ? true : false'
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Switch
for: switchItem
slots:
default:
- component: oh-repeater
config:
filter: '((loop.setpointItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.setpointItem.type=="Number:Temperature")) ? true : false'
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Setpoint,Temperature
for: setpointItem
slots:
default:
- component: oh-button
config:
action: command
actionCommand: =Number(items[loop.setpointItem.name].state.split(' ')[0]) + 0.5
actionItem: =loop.setpointItem.name
iconColor: blue
iconF7: arrow_up_circle
iconSize: 25
style:
background: transparent
height: 35px
display: flex
position: absolute
right: 1%
z-index: 98
visible: '=items[loop.switchItem.name].state == "ON" ? true : false'
- component: oh-button
config:
action: command
actionCommand: =Number(items[loop.setpointItem.name].state.split(' ')[0]) - 0.5
actionItem: =loop.setpointItem.name
iconColor: blue
iconF7: arrow_down_circle
iconSize: 25
style:
background: transparent
bottom: 5%
height: 35px
position: absolute
right: 1%
z-index: 98
visible: '=items[loop.switchItem.name].state == "ON" ? true : false'
- component: oh-repeater
config:
filter: '((loop.switchItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.switchItem.type=="Switch")) ? true : false'
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Switch
for: switchItem
slots:
default:
- component: f7-card-footer
config:
visible: '=items[loop.switchItem.name].state == "ON" ? true : false'
style:
background: rgb(204, 204, 255)
border-radius: 0 0 var(--f7-card-expandable-border-radius) var(--f7-card-expandable-border-radius)
height: auto
slots:
default:
- component: oh-repeater
config:
filter: '((loop.modeItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.modeItem.type=="String")) ? true : false'
fetchMetadata: semantics,metadata,listWidget
sourceType: itemsWithTags
itemTags: Control,Temperature
for: modeItem
slots:
default:
- component: oh-link
config:
action: options
actionItem: =loop.modeItem.name
style:
background: transparent
z-index: 98
slots:
default:
- component: f7-chip
config:
text: =loop.modeItem.label
style:
width: auto
color: white
background: blue
border-radius: 8px
font-size: 15px
font-weight: 500
- component: f7-block
config:
style:
height: auto
padding: 0
display: flex
slots:
default:
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
for: fanspeedItem
sourceType: itemsWithTags
itemTags: Fan
filter: '((loop.fanspeedItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.fanspeedItem.type=="String")) ? true : false'
slots:
default:
- component: oh-link
config:
action: options
actionItem: =loop.fanspeedItem.name
slots:
default:
- component: oh-icon
config:
height: 20px
icon: iconify:material-symbols:mode-fan
style:
color: rgb(191, 0, 255)
margin-top: 3px
- component: oh-repeater
config:
fetchMetadata: semantics,metadata,listWidget
for: fandirectionItem
sourceType: itemsWithTags
itemTags: Tilt
filter: '((loop.fandirectionItem.groupNames.indexOf(props.groupItem) >= 0) && (loop.fandirectionItem.type=="String")) ? true : false'
slots:
default:
- component: oh-link
config:
action: options
actionItem: =loop.fandirectionItem.name
slots:
default:
- component: oh-icon
config:
height: 20px
icon: iconify:gis:direction
style:
color: rgb(191, 0, 255)
margin-top: 3px
margin-left: 10px
Waiting for your opinion!
Cheers!