This is my solution for three inverters
uid: SMA_widget
tags: []
props:
parameters:
- context: item
label: PV Wechselrichter 1
name: power_inverter_1
required: true
type: TEXT
- context: item
label: PV Wechselrichter 2
name: power_inverter_2
required: true
type: TEXT
- context: item
label: PV Wechselrichter 3
name: power_inverter_4
required: true
type: TEXT
- context: item
label: PV Wechselrichter
name: power_inverter
required: true
type: TEXT
- context: item
label: Netzeinspeisung
name: power_grid_to
required: true
type: TEXT
- context: item
label: Netzbezug
name: power_grid_from
required: true
type: TEXT
- context: item
label: Gesamtverbrauch
name: power_load
required: true
type: TEXT
- context: item
label: Batterieleistung
name: power_battery
required: true
type: TEXT
- context: item
label: Batterie Ladezustand
name: battery_soc
required: true
type: TEXT
parameterGroups: []
timestamp: Jul 6, 2023, 1:16:38 PM
component: f7-card
config:
class:
- display-flex
- flex-direction-column
- align-items-center
style:
height: 590px
slots:
content:
- component: f7-block
config:
style:
--f7-theme-color: var(--f7-text-color)
display: flex
justify-content: space-between
padding: 0
slots:
default:
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: row
slots:
default:
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: 0
width: 110px
slots:
default:
- component: oh-icon
config:
height: 110px
icon: sma_pv_2
- component: Label
config:
style:
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: = Math.round(Number.parseFloat(items[props.power_inverter_2].state.split(" ")[0])) + ' ᵂ'
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
flex-grow: 1
slots:
default:
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: 0
width: 110px
slots:
default:
- component: Label
config:
style:
font-size: 25px
font-weight: bold
text-align: center
width: 100px
text: = Math.round(Number.parseFloat(items[props.power_inverter_1].state.split(" ")[0])) + ' ᵂ'
- component: oh-icon
config:
height: 110px
icon: sma_pv_2
style:
margin-top: -20px
- component: f7-block
config:
style:
display: flex
justify-content: center
margin: 0
padding: 0
width: 100%
slots:
default:
- component: f7-row
config:
preserveAspectRatio: xMidYMid slice
style:
height: auto
width: auto
tag: svg
viewBox: 0 0 100 100
xmlns: http://www.w3.org/2000/svg
slots:
default:
- component: f7-row
config:
d: M60 -5 v10 c0 30 10 35 30 35 h20
fill: none
id: path1
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: false
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: false
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path1"
- component: f7-row
config:
d: M40 -5 v10 c0 40 -10 35 -30 35 h-20
fill: none
id: path2
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: false
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: false
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path2"
- component: f7-row
config:
d: M50, 0 v100
fill: none
id: path3
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter_1].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter_1].state.split(" ")[0]) > 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path3"
- component: f7-row
config:
d: M-5 50 l10 0 c40 0 35 10 35 50 l 0 20
fill: none
id: path4
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter_2].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter_2].state.split(" ")[0]) > 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path4"
- component: f7-row
config:
d: M 105 50 l -10 0 c -40 0 -35 10 -35 50 l 0 20
fill: none
id: path5
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter_4].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter_4].state.split(" ")[0]) > 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path5"
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: row
slots:
default:
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: 0
width: 110px
slots:
default:
- component: oh-icon
config:
height: 110px
icon: sma_pv_2
- component: Label
config:
style:
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: = Math.round(Number.parseFloat(items[props.power_inverter_4].state.split(" ")[0])) + ' ᵂ'
- component: f7-block
config:
style:
--f7-theme-color: var(--f7-text-color)
display: flex
justify-content: space-between
padding: 0
slots:
default:
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: row
slots:
default:
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: 0
width: 110px
slots:
default:
- component: oh-icon
config:
height: 110px
icon: sma_grid_2
- component: Label
config:
style:
color: red
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: = Math.round(Number.parseFloat(items[props.power_grid_from].state.split(" ")[0])) + ' ᵂ'
visible: '=(Number.parseFloat(items[props.power_grid_to].state.split(" ")[0]) == 0) ? true : false'
- component: Label
config:
style:
color: green
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: = Math.round(Number.parseFloat(items[props.power_grid_to].state.split(" ")[0])) + ' ᵂ'
visible: '=(Number.parseFloat(items[props.power_grid_to].state.split(" ")[0]) > 0) ? true : false'
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
flex-grow: 1
slots:
default:
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: 0
width: 110px
slots:
default:
- component: oh-icon
config:
height: 110px
icon: sma_pv_2
style:
margin-top: -35px
- component: Label
config:
style:
font-size: 25px
font-weight: bold
text-align: center
margin-right: -200px
margin-top: -70px
width: 100px
text: = Math.round(Number.parseFloat(items[props.power_inverter].state.split(" ")[0])) + ' ᵂ'
- component: f7-block
config:
style:
display: flex
justify-content: center
margin: 0
padding: 0
width: 100%
slots:
default:
- component: f7-row
config:
preserveAspectRatio: xMidYMid slice
style:
height: auto
width: auto
tag: svg
viewBox: 0 0 100 100
xmlns: http://www.w3.org/2000/svg
slots:
default:
- component: f7-row
config:
d: M60 -5 v10 c0 30 10 35 30 35 h20
fill: none
id: path1
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) < 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) < 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path1"
- component: f7-row
config:
d: M40 -5 v10 c0 40 -10 35 -30 35 h-20
fill: none
id: path2
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_grid_to].state.split(" ")[0]) > 0 && Number.parseFloat(items[props.power_grid_from].state.split(" ")[0]) == 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_grid_to].state.split(" ")[0]) > 0 && Number.parseFloat(items[props.power_grid_from].state.split(" ")[0]) == 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path2"
- component: f7-row
config:
d: M50, 0 v100
fill: none
id: path3
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter].state.split(" ")[0]) - (Number.parseFloat(items[props.power_grid_to].state.split(" ")[0]) + Math.abs(Number.parseFloat(items[props.power_battery].state.split(" ")[0]))) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_inverter].state.split(" ")[0]) - (Number.parseFloat(items[props.power_grid_to].state.split(" ")[0]) + Math.abs(Number.parseFloat(items[props.power_battery].state.split(" ")[0]))) > 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path3"
- component: f7-row
config:
d: M-5 50 l10 0 c40 0 35 10 35 50 l 0 20
fill: none
id: path4
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_grid_from].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_grid_from].state.split(" ")[0]) > 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path4"
- component: f7-row
config:
d: M 105 50 l -10 0 c -40 0 -35 10 -35 50 l 0 20
fill: none
id: path5
stroke: rgba(100, 150, 200, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 6
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) > 0) ? true : false'
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: 4s
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#path5"
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: -10px
width: 110px
slots:
default:
- component: oh-icon
config:
color: orange
height: 110px
icon: sma_consumption_2
- component: Label
config:
style:
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: =Math.round(Number.parseFloat(items[props.power_load].state.split(" ")[0])) + ' ᵂ'
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: row
slots:
default:
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 110px
justify-content: center
margin-top: -40px
width: 110px
slots:
default:
- component: oh-link
config:
iconColor: red
iconF7: battery_0
iconSize: 33px
style:
font-size: 25px
font-weight: bold
white-space: nowrap
text: =items[props.battery_soc].state.split(" ")[0] + ' ᵂ'
visible: '=(Number.parseFloat(items[props.battery_soc].state.split(" ")[0]) < 10) ? true : false'
- component: oh-link
config:
iconColor: orange
iconF7: battery_25
iconSize: 33px
style:
font-size: 25px
font-weight: bold
white-space: nowrap
text: =items[props.battery_soc].state.split(" ")[0] + ' ᵂ'
visible: '=(Number.parseFloat(items[props.battery_soc].state.split(" ")[0]) >= 10 && Number.parseFloat(items[props.battery_soc].state.split(" ")[0]) < 75) ? true : false'
- component: oh-link
config:
iconColor: green
iconF7: battery_100
iconSize: 33px
style:
font-size: 25px
font-weight: bold
white-space: nowrap
text: =items[props.battery_soc].state.split(" ")[0] + ' ᵂ'
visible: '=(Number.parseFloat(items[props.battery_soc].state.split(" ")[0]) >= 75) ? true : false'
- component: oh-icon
config:
height: 110px
icon: sma_battery_2
style:
margin-top: -20px
visible: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) !== 0) ? true : false'
- component: Label
config:
style:
color: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) > 0) ? "red" : "green"'
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
white-space: nowrap
width: 100px
text: =Math.abs(Number.parseFloat(items[props.power_battery].state.split(" ")[0])) + ' ᵂ'
visible: '=(Number.parseFloat(items[props.power_battery].state.split(" ")[0]) !== 0) ? true : false'
i did also some update for battery. if you have no battery in your system it won’t be shown