I have created a new widget for energy monitoring for my house. Huge thanks to others who gave me inspiration for how to get it done. It features areas for solar, grid, house, car, battery and hot water diverter (eddi). It also uses svg graphics to show energy flows and some simple gradient fills to indicate levels for each of the different areas. Hope it might be of use to someone. Next steps will be to make the individual areas clikable so it can go through to a graph and i also hope to add a section for boiler operation once i have a monitoring system for boiler running.
uid: test_svg
tags: []
props:
parameters:
- context: item
description: Daily Solar
label: dailySolar
name: dailySolar
required: false
type: TEXT
- context: item
description: Power Solar
label: powerSolar
name: powerSolar
required: false
type: TEXT
- context: item
description: Daily Grid In
label: dailyGridIn
name: dailyGridIn
required: false
type: TEXT
- context: item
description: Daily Grid Out
label: dailyGridOut
name: dailyGridOut
required: false
type: TEXT
- context: item
description: Power Grid
label: powerGrid
name: powerGrid
required: false
type: TEXT
- context: item
description: Battery Power
label: batteryPower
name: batteryPower
required: false
type: TEXT
- context: item
description: Battery Pct
label: batteryPct
name: batteryPct
required: false
type: TEXT
- context: item
description: Power Eddi
label: powerEddi
name: powerEddi
required: false
type: TEXT
- context: item
description: Daily Eddi
label: dailyEddi
name: dailyEddi
required: false
type: TEXT
- context: item
description: Temp Eddi
label: tempEddi
name: tempEddi
required: false
type: TEXT
- context: item
description: Temp Status
label: statusEddi
name: statusEddi
required: false
type: TEXT
- context: item
description: EV Power
label: evPower
name: evPower
required: false
type: TEXT
- context: item
description: EV Pct
label: evPct
name: evPct
required: false
type: TEXT
- context: item
description: EV Range
label: evRange
name: evRange
required: false
type: TEXT
- context: item
description: EV Charge Status
label: evChargeStatus
name: evChargeStatus
required: false
type: TEXT
- context: item
description: EV Connect Status
label: evConnectStatus
name: evConnectStatus
required: false
type: TEXT
- context: item
description: House power
label: powerHouse
name: powerHouse
required: false
type: TEXT
- context: item
description: House Today
label: todayHouse
name: todayHouse
required: false
type: TEXT
parameterGroups: []
timestamp: Mar 30, 2025, 1:49:37 PM
component: f7-block
config:
style:
width: 700px
slots:
default:
- component: f7-row
config:
style:
height: 90px
display: flex
slots:
default:
- component: f7-col
config:
style:
width: 5%
height: 70px
- component: f7-col
config:
align: center
style:
width: 15%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
border: 1px solid rgba(255, 255, 0, 0.5)
border-radius: 10px
background: ='linear-gradient(to top, rgba(255, 255, 0, 0.5) ' +
(items[props.powerSolar].state / 4000 * 100) + '%, black 0% )'
slots:
default:
- component: oh-icon
config:
icon: f7:sun_maxx
- component: Label
config:
text: ='Today ' + items[props.dailySolar].state / 10 + ' kWh'
style:
font-size: 12px
- component: Label
config:
text: =items[props.powerSolar].state + ' W'
style:
font-size: 12px
- component: f7-col
config:
style:
width: 25%
height: 100%
slots:
default:
- component: svg
config:
viewBox: 0 0 170 50
xlmns: http://www.w3.org/2000/svg
style:
height: 100%
width: 100%
slots:
default:
- component: path
config:
id: path7
d: M 0 35 L 121 35 A 35 35 0 0 1 156 70
stroke: yellow
stroke-width: 1
vector-effect: non-scaling-stroke
fill: none
- component: circle
config:
cx: 0
cy: 0
r: 4
fill: yellow
visible: =(items[props.powerSolar].state) == 0 ? false:true
slots:
default:
- component: animateMotion
config:
begin: 0s;
calcMode: linear
dur: 2s
repeatCount: indefinite
slots:
default:
- component: mpath
config:
href: "#path7"
- component: f7-col
config:
align: center
style:
width: 10%
height: 100%
- component: f7-col
config:
style:
width: 25%
height: 100%
slots:
default:
- component: svg
config:
viewBox: 0 0 170 50
xlmns: http://www.w3.org/2000/svg
style:
height: 100%
width: 100%
slots:
default:
- component: path
config:
id: path8
d: M 0 70 A 35 35 0 0 1 35 35 L 170 35
stroke: orange
stroke-width: 1
vector-effect: non-scaling-stroke
visible: =(items[props.evConnectStatus].state) == 'disconnected' ? false:true
fill: none
- component: circle
config:
cx: 0
cy: 0
r: 4
fill: orange
visible: =(items[props.evPower].state) == 0 ? false:true
slots:
default:
- component: animateMotion
config:
begin: 0s;
calcMode: linear
dur: 3s
repeatCount: indefinite
slots:
default:
- component: mpath
config:
href: "#path8"
- component: f7-col
config:
align: center
style:
width: 15%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
border: 1px solid rgba(255, 165, 0, 0.5)
border-radius: 10px
background: ='linear-gradient(to top, rgba(255, 165, 0, 0.5) ' +
(items[props.evPct].state) + '%, black 0% )'
slots:
default:
- component: oh-icon
config:
icon: f7:car_fill
- component: Label
config:
text: =items[props.evPower].state + ' kW'
style:
font-size: 12px
- component: Label
config:
text: =items[props.evPct].state + " % | " + items[props.evRange].state + "km"
style:
font-size: 12px
- component: Label
config:
text: =items[props.evChargeStatus].state
style:
font-size: 10px
- component: f7-col
config:
style:
width: 5%
height: 70px
- component: f7-row
config:
style:
width: 100%
height: 90px
slots:
default:
- component: f7-col
config:
align: center
style:
width: 20%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
- component: f7-col
config:
align: center
style:
width: 20%
height: 100%
- component: f7-col
config:
align: center
style:
width: 20%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
border: 1px solid purple
border-radius: 20px
slots:
default:
- component: oh-icon
config:
icon: f7:house
- component: Label
config:
text: ='Today ' + items[props.todayHouse].state / 10 + ' kWh'
style:
font-size: 12px
- component: Label
config:
text: =items[props.powerHouse].state + ' kW'
style:
font-size: 12px
- component: f7-col
config:
style:
width: 20%
height: 100%
slots:
default:
- component: svg
config:
viewBox: 0 0 156 70
xlmns: http://www.w3.org/2000/svg
style:
height: 100%
width: 100%
slots:
default:
- component: path
config:
id: path11
d: '=(items[props.batteryPower].numericState) < 0 ? "M 156 35 L 0 35" : "M 0 35
L 156 35"'
stroke: green
stroke-width: 1
vector-effect: non-scaling-stroke
fill: none
- component: circle
config:
cx: 0
cy: 0
r: 4
fill: green
slots:
default:
- component: animateMotion
config:
begin: 0s;
calcMode: linear
dur: 3.5s
repeatCount: indefinite
slots:
default:
- component: mpath
config:
href: "#path11"
- component: f7-col
config:
align: center
style:
width: 15%
height: 100%
border: 1px solid rgba(0, 128, 0, 0.5)
border-radius: 10px
background: ='linear-gradient(to top, rgba(0, 128, 0, 0.5) ' +
(items[props.batteryPct].state) + '%, black 0% )'
slots:
default:
- component: oh-icon
config:
icon: f7:battery_25
- component: Label
config:
text: =items[props.batteryPower].state
style:
font-size: 12px
- component: Label
config:
text: =items[props.batteryPct].state + ' %'
style:
font-size: 12px
- component: f7-col
config:
style:
width: 5%
height: 70px
- component: f7-row
config:
style:
width: 100%
height: 90px
slots:
default:
- component: f7-col
config:
align: center
style:
width: 5%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
- component: f7-col
config:
align: center
style:
width: 15%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
background: ='linear-gradient(' + ((items[props.powerGrid].state) > 0 ? "to
top":"to bottom") + ', rgba(255, 0, 0, 0.5) '
+ Math.abs(items[props.powerGrid].state)/10000 * 100 + '%,
black 0% )'
border: 1px solid rgba(255, 0, 0, 0.5)
border-radius: 10px
slots:
default:
- component: oh-icon
config:
icon: if:mdi:transmission-tower
- component: Label
config:
text: ='In ' + items[props.dailyGridIn].state / 10 + ' kWh'
style:
font-size: 12px
- component: Label
config:
text: ='Out ' + items[props.dailyGridOut].state / 10 + ' kWh'
style:
font-size: 12px
- component: Label
config:
text: =items[props.powerGrid].state + ' W'
style:
font-size: 12px
- component: f7-col
config:
style:
width: 25%
height: 100%
slots:
default:
- component: svg
config:
viewBox: 0 0 170 90
xlmns: http://www.w3.org/2000/svg
style:
height: 100%
width: 100%
slots:
default:
- component: path
config:
id: path9
d: '=(items[props.powerGrid].state) < 0 ? "M 156 0 A 35 35 0 0 1 121 35 L 0 35 "
: "M 0 35 L 121 35 A 35 35 0 0 0 156 0"'
stroke: red
stroke-width: 1
vector-effect: non-scaling-stroke
fill: none
- component: circle
config:
cx: 0
cy: 0
r: 4
fill: red
visible: true
slots:
default:
- component: animateMotion
config:
begin: 0s;
calcMode: linear
dur: 3s
repeatCount: indefinite
slots:
default:
- component: mpath
config:
href: "#path9"
- component: f7-col
config:
align: center
style:
width: 10%
height: 100%
slots:
default:
- component: Label
config:
style:
font-size: 12px
- component: f7-col
config:
style:
width: 25%
height: 100%
slots:
default:
- component: svg
config:
viewBox: 0 0 170 90
xlmns: http://www.w3.org/2000/svg
style:
height: 100%
width: 100%
slots:
default:
- component: path
config:
id: path10
d: M 0 0 A 35 35 0 0 0 35 35 L 170 35
stroke: blue
stroke-width: 1
vector-effect: non-scaling-stroke
fill: none
- component: circle
config:
cx: 0
cy: 0
r: 4
fill: blue
visible: =(items[props.powerEddi].state) == 0 ? false:true
slots:
default:
- component: animateMotion
config:
begin: 0s;
calcMode: linear
dur: 2s
repeatCount: indefinite
slots:
default:
- component: mpath
config:
href: "#path10"
- component: f7-col
config:
align: center
style:
width: 15%
height: 100%
display: flex
align-items: center
justify-content: space-around
flex-direction: column
background: ='linear-gradient(to top, rgba(0, 0, 255, 0.5) ' +
(items[props.tempEddi].state/60 * 100) + '%, black 0% )'
border: 1px solid rgba(0, 0, 255, 0.5)
border-radius: 10px
slots:
default:
- component: oh-icon
config:
icon: f7:thermometer
- component: Label
config:
text: ='Today ' + Math.round(items[props.dailyEddi].state * 100)/100 + ' kWh'
style:
font-size: 12px
- component: Label
config:
text: =items[props.powerEddi].state + ' kW | ' + items[props.tempEddi].state +
' C'
style:
font-size: 12px
- component: Label
config:
text: =items[props.statusEddi].displayState
style:
font-size: 10px
- component: f7-col
config:
style:
width: 5%
height: 70px