I have the follow widget which is based on PV status widget for sungrow inverters with the icons from Animated Energy Widget - #98 by noobihabi.
How can I make sure it is in the center of the card and not on the left side?
Below the widget code
Summary
uid: sungrowInverterStatus
tags:
- card
props:
parameters:
- default: PV Status
label: Header Text
name: headerText
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Total_DC_Power
label: Solar Power
name: solarPower
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Daily_PV_Generation
description: Solar Energy
label: Solar Energy
name: solarEnergy
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Load_Power
description: Current Load Power
label: Power Consumption Home
name: loadPower
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Daily_Import_Energy
label: Daily Import Energy
name: importEnergy
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Daily_Direct_Energy_Consumption
description: Daily Direct Energy Consumption
name: directEnergyConsumption
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Export_Power
description: Export Power
name: exportPower
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Daily_Export_Energy
description: Daily Export Energy
name: exportEnergy
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Battery_Level
description: Battery Level
name: batteryLevel
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Daily_Charge_Energy
description: Battery Charge Energy
name: batteryChargeEnergy
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Daily_Battery_Discharge_Energy
description: Battery Discharge Energy
name: batteryDischargeEnergy
required: true
type: TEXT
- context: item
default: Sungrow_Inverter_Battery_Power
description: Battery Power
name: batteryPower
required: true
type: TEXT
parameterGroups:
- name: solarAction
context: action
label: Solar Action
description: Action to perform when the solar icon is clicked
- name: loadAction
context: action
label: Load Action
description: Action to perform when the load icon is clicked
timestamp: May 23, 2025, 10:17:46 PM
component: oh-context
config:
constants: {}
functions:
getFormattedState: =(item) => (@item).replace('-', '').replace('kWh',
'ᵏᵂʰ').replace('kW', 'ᵏᵂ').replace('W', 'ᵂ')
isNegative: =(item) => @item !== undefined && Number((@item).split('
')[0].replace(',', '.')) < 0
isOnBackupPower: =() => props.backuppower && (@@props.backuppower === 'OPEN' ||
@@props.backuppower === 'ON')
isPositive: =(item) => @item !== undefined && Number((@item).split('
')[0].replace(',', '.')) > 0
variable: {}
slots:
default:
- component: f7-card
config:
style:
border-radius: var(--f7-card-expandable-border-radius)
box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
height: 390px
margin-left: 5px
margin-right: 5px
min-width: 350px
title: =props.headerText
slots:
default:
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="80"
x2="150" y2="205"
style="stroke:lightgrey;stroke-width:3"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="80"
x2="150" y2="205" style="stroke:rgba(100, 150,
200);stroke-width:3"/><polygon points="144,140 156,140
150,147" fill="rgba(100, 150, 200)"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
visible: =Number.parseFloat(items[props.solarPower].state) > 0
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205"
x2="250" y2="267"
style="stroke:lightgrey;stroke-width:3"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205"
x2="250" y2="267" style="stroke:rgba(100, 150,
200);stroke-width:3"/><polygon points="194,236 206,236
200,243" fill="rgba(100, 150, 200)" transform="rotate(120 200
236)"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
visible: =Number.parseFloat(items[props.exportPower].state) < 0
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205"
x2="50" y2="267"
style="stroke:lightgrey;stroke-width:3"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205"
x2="50" y2="267" style="stroke:rgba(100, 150,
200);stroke-width:3"/><polygon points="94,236 106,236 100,243"
fill="rgba(100, 150, 200)" transform="rotate(-120 100
236)"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
visible: =Number.parseFloat(items[props.batteryPower].state) > 0 &&
Number.parseFloat(items[props.loadPower].state) >
Number.parseFloat(items[props.solarPower].state)
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125
0 0 1 250 267" stroke="lightgrey" stroke-width="3"
fill="none"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125
0 0 1 250 267" stroke="rgba(100, 150, 200)" stroke-width="3"
fill="none"/><polygon points="239,133 251,133 245,128"
fill="rgba(100, 150, 200)" transform="rotate(140 245
133)"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
visible: =Number.parseFloat(items[props.exportPower].state) > 0
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125
0 0 0 50 267" stroke="lightgrey" stroke-width="3"
fill="none"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125
0 0 0 50 267" stroke="rgba(100, 150, 200)" stroke-width="3"
fill="none"/><polygon points="61,133 49,133 55,138"
fill="rgba(100, 150, 200)" transform="rotate(40 55
133)"/></svg>')
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
visible: =Number.parseFloat(items[props.batteryPower].state) > 0 &&
Number.parseFloat(items[props.loadPower].state) <
Number.parseFloat(items[props.solarPower].state)
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><path d="M 257 267 A 125
125 0 0 1 50 267" stroke="lightgrey" stroke-width="3"
fill="none"/></svg>')
border-style: solid
border-width: 0px
height: 327px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
- component: f7-block
config:
style:
background-image: url('data:image/svg+xml,<svg
xmlns="http://www.w3.org/2000/svg"><path d="M 257 267 A 125
125 0 0 1 50 267" stroke="rgba(100, 150, 200)"
stroke-width="3" fill="none"/><polygon points="144,323 156,323
150,328" fill="rgba(100, 150, 200)" transform="rotate(270 150
322)"/></svg>')
border-style: solid
border-width: 0px
height: 330px
left: 0px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 35px
width: 350px
visible: =Number.parseFloat(items[props.batteryPower].state) > 0 &&
Number.parseFloat(items[props.loadPower].state) >
Number.parseFloat(items[props.solarPower].state) &&
Number.parseFloat(items[props.batteryPower].state) >
Number.parseFloat(items[props.loadPower].state)
- component: f7-block
config:
style:
background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
border-color: white
border-radius: 50%
border-style: solid
border-width: 2px
height: 60px
left: 120px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 85px
width: 60px
- component: f7-block
config:
style:
background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
border-color: white
border-radius: 50%
border-style: solid
border-width: 2px
height: 60px
left: 120px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 200px
width: 60px
- component: f7-block
config:
style:
background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
border-color: white
border-radius: 50%
border-style: solid
border-width: 2px
height: 60px
left: 216px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 272px
width: 60px
- component: f7-block
config:
style:
background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
border-color: white
border-radius: 50%
border-style: solid
border-width: 2px
height: 60px
left: 20px
margin-left: auto
margin-right: auto
margin-top: auto
position: absolute
top: 272px
width: 60px
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 130px
justify-content: center
position: absolute
width: 300px
slots:
default:
- component: oh-icon
config:
actionPropsParameterGroup: solarAction
height: 85px
icon: oh:sma-energy:pv
style:
margin-bottom: 10px
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 510px
justify-content: center
position: absolute
width: 500px
slots:
default:
- component: oh-icon
config:
height: 85px
icon: oh:sma-energy:grid
style:
margin-bottom: 10px
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 390px
justify-content: center
position: absolute
width: 300px
slots:
default:
- component: oh-icon
config:
actionPropsParameterGroup: loadAction
height: 85px
icon: oh:sma-energy:house
style:
margin-bottom: 10px
- component: f7-block
config:
style:
align-items: center
display: flex
flex-direction: column
height: 510px
justify-content: center
position: absolute
width: 90px
slots:
default:
- component: oh-icon
config:
height: 85px
icon: oh:sma-energy:battery
style:
margin-bottom: 10px
- component: f7-block
config:
style:
border-style: solid
border-width: 0px
height: 350px
left: 0px
margin-left: auto
margin-right: auto
margin-top: 10px
position: absolute
text-align: right
width: 350px
slots:
default:
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 130px
position: absolute
top: 0px
width: 60px
text: =(items[props.solarPower].state)
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 130px
position: absolute
top: 15px
width: 60px
text: =(items[props.solarEnergy].state)
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 90px
position: absolute
top: 105px
width: 50px
text: = Math.min(Number.parseFloat(items[props.loadPower].state),
Number.parseFloat(items[props.solarPower].state)) + " " +
items[props.loadPower].state.split(" ")[1]
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 90px
position: absolute
top: 120px
width: 50px
text: =(items[props.directEnergyConsumption].state)
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 120px
position: absolute
top: 215px
width: 50px
text: =(items[props.loadPower].state)
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 120px
position: absolute
top: 230px
width: 50px
text: = (Number.parseFloat(items[props.importEnergy].state) +
Number.parseFloat(items[props.directEnergyConsumption].state)
+
Number.parseFloat(items[props.batteryDischargeEnergy].state)).toFixed(1)
+ " " + items[props.importEnergy].state.split(" ")[1]
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 250px
position: absolute
top: 80px
width: 60px
text: "=Number.parseFloat(items[props.exportPower].state) > 0 ?
items[props.exportPower].state : '0 W'"
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 250px
position: absolute
top: 95px
width: 60px
text: =items[props.exportEnergy].state
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 180px
position: absolute
top: 185px
width: 60px
text: "=Number.parseFloat(items[props.exportPower].state) < 0 ?
Math.abs(Number.parseFloat(items[props.exportPower].state\
)) + ' W' : '0 W'"
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 180px
position: absolute
top: 200px
width: 60px
text: =items[props.importEnergy].state
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: -10px
position: absolute
top: 80px
width: 60px
text: "=Number.parseFloat(items[props.loadPower].state) <
Number.parseFloat(items[props.solarPower].state) ?
items[props.batteryPower].state : '0 W'"
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: -10px
position: absolute
top: 95px
width: 60px
text: =items[props.batteryChargeEnergy].state
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 40px
position: absolute
top: 185px
width: 60px
text: "=Number.parseFloat(items[props.loadPower].state) >
Number.parseFloat(items[props.solarPower].state) ?
items[props.batteryPower].state : '0 W'"
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 40px
position: absolute
top: 200px
width: 60px
text: =items[props.batteryDischargeEnergy].state
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 10px
position: absolute
top: 280px
width: 60px
text: =items[props.batteryLevel].displayState
- component: Label
config:
style:
font-size: 12px
font-weight: bold
left: 120px
position: absolute
top: 310px
width: 50px
text: "=Number.parseFloat(items[props.batteryPower].state) <= 0 ||
Number.parseFloat(items[props.loadPower].state) <
Number.parseFloat(items[props.solarPower].state) ||
Number.parseFloat(items[props.batteryPower].state) <=
Number.parseFloat(items[props.loadPower].state) ? '0 W' :
(Number.parseFloat(items[props.batteryPower].state) -
Number.parseFloat(items[props.loadPower].state)).toFixed(\
1) + ' W'"