Hi to Everyone,
this is a fork of Deye Inverter Widget with the following additions:
- progressbar on power indications and battery SOC
- tailored to Huawei Solar2000+Luna2000 variable set
- added wallbox consumption as separate item
What you need to change to fit to your house:
on each progress bar you have to modify 3200 to your max power of each component, in my case is in Watt.
=(Number.parseFloat(items[props.itemXXXXXX].state)/3200*100)
This is required to rescale correctly progress bars, I did not pull them outside widget to avoid too may paramenter to be set being setting is usually once in a life.
uid: Kiosk_Inverter_Widget_ProgressBar_ByDJD
tags: []
props:
parameters:
- description: Title
label: Title
name: title
required: false
type: TEXT
- context: item
description: Power From Grid
label: Power From Grid Item
name: itemConsumptionFromGrid
required: true
type: TEXT
- context: item
description: Daily Energy From Grid
label: Daily Energy From Grid Item
name: itemDailyConsumptionFromGrid
required: false
type: TEXT
- context: item
description: Daily Energy To Grid
label: Daily Energy To Grid
name: itemDailyProductionToGrid
required: false
type: TEXT
- context: item
description: Inverter Temperature
label: Inverter Temperature
name: itemInverterTemperature
required: false
type: TEXT
- context: item
description: Solar Power
label: Solar Power Item
name: itemSolar
required: false
type: TEXT
- context: item
description: Solar Daily Energy
label: Solar Daily Energy Item
name: itemDailySolar
required: false
type: TEXT
- context: item
description: Home Power
label: Home Power Item
name: itemHomeConsumption
required: false
type: TEXT
- context: item
description: Daily Home Energy
label: Daily Home Energy Item
name: itemDailyHomeConsumption
required: false
type: TEXT
- context: item
description: Battery Power
label: Battery Power Item
name: itemBatteryConsumption
required: false
type: TEXT
- context: item
description: Daily Battery Energy
label: Daily Battery Energy Item
name: itemDailyBatteryConsumption
required: false
type: TEXT
- context: item
description: Daily Battery Charge Energy
label: Daily Battery Charge Energy Item
name: itemDailyBatteryCharge
required: false
type: TEXT
- context: item
description: Battery SOC
label: Battery SOC Item
name: itemBatterySOC
required: false
type: TEXT
- context: item
description: Daily Inverter Energy
label: Daily Inverter Energy
name: itemDailyInverterPower
required: false
type: TEXT
- context: item
description: Daily Wallbox Energy
label: Daily Wallbox Energy
name: itemDailyWallboxEnergy
required: false
type: TEXT
- context: item
description: Daily Wallbox Power
label: Daily Wallbox Power
name: itemDailyWallboxPower
required: false
type: TEXT
- context: item
description: Battery Temperature
label: Battery Temperature
name: itemBatteryTemperature
required: false
type: TEXT
- context: item
description: Inverter Power
label: Inverter Power
name: itemInverterPower
required: false
type: TEXT
- context: item
description: Inverter Status
label: Inverter Status
name: itemInverterStatus
required: false
type: TEXT
- context: item
description: Battery Status
label: Battery Status
name: itemBatteryStatus
required: false
type: TEXT
parameterGroups: []
timestamp: Apr 25, 2026, 8:57:05 PM
component: f7-card
config:
style:
background: "linear-gradient(to bottom, #212121, #333333)"
border-radius: 20px
height: 440px
title: = props.title
slots:
content:
- component: f7-block
config:
style:
margin: 0
padding: 0
slots:
default:
- component: f7-block
config:
style:
--f7-block-font-size: 18px
--f7-theme-color: var(--f7-text-color)
display: flex
justify-content: center
margin: 0
padding: 0
slots:
default:
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
slots:
default:
- component: f7-block
config:
style:
align-items: center
border: 3px solid orange
border-radius: 20px
display: flex
flex-direction: column
height: 170px
justify-content: center
width: 125px
slots:
default:
- component: oh-link
config:
iconColor: orange
iconF7: arrow_right
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: =items[props.itemDailySolar].displayState
- component: oh-icon
config:
color: orange
height: 40px
icon: if:mdi:solar-power
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Number.parseFloat(items[props.itemSolar].state)/3200*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: orange
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =items[props.itemSolar].displayState
- component: f7-block
config:
style:
align-items: center
flex-direction: column
height: 20px
justify-content: center
width: 90px
- component: f7-block
config:
style:
align-items: center
border: 3px solid teal
border-radius: 20px
display: flex
flex-direction: column
height: 170px
justify-content: center
width: 125px
slots:
default:
- component: oh-link
config:
iconColor: green
iconF7: arrow_left
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: = items[props.itemDailyBatteryCharge].displayState
- component: oh-link
config:
iconColor: red
iconF7: arrow_right
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: = items[props.itemDailyBatteryConsumption].displayState
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Number.parseFloat(items[props.itemBatterySOC].state)/100*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: teal
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =items[props.itemBatterySOC].displayState
- component: oh-link
config:
iconColor: teal
iconF7: thermometer
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: =items[props.itemBatteryTemperature].displayState
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state))/3600*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: "=(Number.parseInt(items[props.itemBatteryConsumption].state)
< 0) ? 'red' : 'green'"
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) +
' W'
- component: Label
config:
text: =items[props.itemBatteryStatus].displayState
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
slots:
default:
- component: f7-col
config:
preserveAspectRatio: xMidYMid slice
style:
height: 390px
width: 20px
tag: svg
viewBox: 0 0 10 150
xmlns: http://www.w3.org/2000/svg
slots:
default:
- component: f7-row
config:
d: M0,35 h2 q3,0 3,15 t3,15 h2
fill: none
id: solarpath
stroke: orange
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
- component: f7-row
config:
fill: orange
r: 2
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: "=(Math.abs(Number.parseFloat(items[props.itemSolar].state)) < 10.0) ?
false : true"
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: |-
=(Number.parseFloat(items[props.itemSolar].state) > 2500) ? '1s' :
(Number.parseFloat(items[props.itemSolar].state) > 2000) ? '2s' :
(Number.parseFloat(items[props.itemSolar].state) > 1500) ? '3s' :
(Number.parseFloat(items[props.itemSolar].state) > 1000) ? '4s' :
(Number.parseFloat(items[props.itemSolar].state) > 500) ? '6s' :
(Number.parseFloat(items[props.itemSolar].state) > 100) ? '8s' :'16s'
keyPoints: "=(Number.parseFloat(items[props.itemSolar].state) < 0) ? '1;0' :
'0;1'"
keyTimes: 0;1
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#solarpath"
- component: f7-row
config:
d: M0,115 h2 q3,0 3,-15 t3,-15 h2
fill: none
id: batterypath
stroke: teal
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
- component: f7-row
config:
fill: teal
r: 2
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: "=(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].stat\
e)) < 10.0) ? false : true"
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: |-
=(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) > 3000) ? '1s' :
(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) > 2000) ? '2s' :
(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) > 1500) ? '3s' :
(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) > 1000) ? '4s' :
(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) > 500) ? '6s' :
(Math.abs(Number.parseFloat(items[props.itemBatteryConsumption].state)) > 100) ? '8s' :'16s'
keyPoints: "=(Number.parseFloat(items[props.itemBatteryConsumption].state) > 0)
? '1;0' : '0;1'"
keyTimes: 0;1
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#batterypath"
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
slots:
default:
- component: f7-block
config:
style:
align-items: center
flex-direction: column
height: 90px
justify-content: center
width: 90px
- component: f7-block
config:
style:
align-items: center
border: 2px solid green
border-radius: 20px
display: flex
flex-direction: column
height: 170px
justify-content: center
width: 125px
slots:
default:
- component: oh-link
config:
iconColor: red
iconF7: arrow_right
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: =items[props.itemDailyInverterPower].displayState
- component: oh-icon
config:
color: green
height: 40px
icon: if:cbi:huawei-solar-inverter
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Math.abs(Number.parseFloat(items[props.itemInverterPower].state))/3650*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: green
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =Math.abs(Number.parseFloat(items[props.itemInverterPower].state)) + ' W'
- component: oh-link
config:
iconColor: green
iconF7: thermometer
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: =items[props.itemInverterTemperature].displayState
- component: Label
config:
text: =items[props.itemInverterStatus].state
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
slots:
default:
- component: f7-col
config:
preserveAspectRatio: xMidYMid slice
style:
height: 390px
width: 20px
tag: svg
viewBox: 0 0 10 150
xmlns: http://www.w3.org/2000/svg
slots:
default:
- component: f7-row
config:
d: M10,35 h-2 q-3,0 -3,15 t-3,15 h-2
fill: none
id: gridpath
stroke: darkred
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
- component: f7-row
config:
fill: darkred
r: 2
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: "=(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].sta\
te)) < 10.0) ? false : true"
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: |-
=(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) > 3000) ? '1s' :
(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) > 2000) ? '2s' :
(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) > 1500) ? '3s' :
(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) > 1000) ? '4s' :
(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) > 500) ? '6s' :
(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) > 100) ? '8s' :'16s'
keyPoints: "=(Number.parseFloat(items[props.itemConsumptionFromGrid].state) > 0)
? '1;0' : '0;1'"
keyTimes: 0;1
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#gridpath"
- component: f7-row
config:
d: M0,85 h2 q3,0 3,15 t3,15 h2
fill: none
id: loadpath
stroke: blue
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
- component: f7-row
config:
fill: blue
r: 2
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: "=(Math.abs(Number.parseFloat(items[props.itemHomeConsumption].state))
< 10.0) ? false : true"
slots:
default:
- component: f7-row
config:
calcMode: linear
dur: |-
=((Number.parseFloat(items[props.itemHomeConsumption].state)) + (Number.parseFloat(items[props.itemDailyWallboxPower].state)) > 3000) ? '1s' :
((Number.parseFloat(items[props.itemHomeConsumption].state)) + (Number.parseFloat(items[props.itemDailyWallboxPower].state)) > 2000) ? '2s' :
((Number.parseFloat(items[props.itemHomeConsumption].state)) + (Number.parseFloat(items[props.itemDailyWallboxPower].state)) > 1500) ? '3s' :
((Number.parseFloat(items[props.itemHomeConsumption].state)) + (Number.parseFloat(items[props.itemDailyWallboxPower].state)) > 1000) ? '4s' :
((Number.parseFloat(items[props.itemHomeConsumption].state)) + (Number.parseFloat(items[props.itemDailyWallboxPower].state)) > 500) ? '6s' :
((Number.parseFloat(items[props.itemHomeConsumption].state)) + (Number.parseFloat(items[props.itemDailyWallboxPower].state)) > 100) ? '8s' :'16s'
keyPoints: "=(Number.parseFloat(items[props.itemHomeConsumption].state) > 0) ?
'0;1' : '1;0'"
keyTimes: 0;1
repeatCount: indefinite
tag: animateMotion
slots:
default:
- component: f7-row
config:
tag: mpath
xlink:href: "#loadpath"
- component: f7-col
config:
style:
align-items: center
display: flex
flex-direction: column
slots:
default:
- component: f7-block
config:
style:
align-items: center
border: 3px solid darkred
border-radius: 20px
display: flex
flex-direction: column
height: 170px
justify-content: center
width: 125px
slots:
default:
- component: oh-link
config:
iconColor: green
iconF7: arrow_right
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: = items[props.itemDailyProductionToGrid].displayState
- component: oh-link
config:
iconColor: red
iconF7: arrow_left
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: = items[props.itemDailyConsumptionFromGrid].displayState
- component: oh-icon
config:
color: darkred
height: 40px
icon: if:mdi:transmission-tower
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state))/5000*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: "=(Number.parseInt(items[props.itemConsumptionFromGrid].state)
< 0) ? 'red' : 'green'"
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =Math.abs(Number.parseFloat(items[props.itemConsumptionFromGrid].state)) +
' W'
- component: f7-block
config:
style:
align-items: center
flex-direction: column
height: 20px
justify-content: center
width: 90px
- component: f7-block
config:
style:
align-items: center
border: 3px solid blue
border-radius: 20px
display: flex
flex-direction: column
height: 170px
justify-content: center
width: 125px
slots:
default:
- component: oh-icon
config:
color: blue
height: 30px
icon: iconify:mdi:ev-plug-type2
- component: oh-link
config:
iconColor: blue
iconF7: arrow_right
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: =items[props.itemDailyWallboxEnergy].displayState
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Number.parseFloat(items[props.itemDailyWallboxPower].state)/4500*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: blue
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =items[props.itemDailyWallboxPower].displayState
- component: oh-icon
config:
color: blue
height: 30px
icon: iconify:bi:house-fill
- component: oh-link
config:
iconColor: blue
iconF7: arrow_right
iconSize: 18px
style:
font-size: 18px
pointer-events: none
white-space: nowrap
text: =items[props.itemDailyHomeConsumption].displayState
- component: f7-block
config:
style:
height: 20px
position: relative
width: 125px
slots:
default:
- component: f7-progressbar
config:
progress: =(Number.parseFloat(items[props.itemHomeConsumption].state)/4500*100)
style:
--f7-progressbar-bg-color: black
--f7-progressbar-height: 100%
--f7-progressbar-width: 100%
--f7-theme-color: blue
- component: Label
config:
style:
align-items: center
display: flex
font-size: 16px
font-weight: bold
height: 100%
justify-content: center
left: 0
pointer-events: none
position: absolute
top: 0
width: 100%
text: =items[props.itemHomeConsumption].displayState
