This looks really cool. I’m not yet in a position to add this widget to my OH pages because I still have quite a few issues with my hardware (e.g. expecting to replace my PV inverter with a new one). I have also looked at the other widget in this topic.
Looks nice. But (as there is always a but) Arrows doesn’t show actual directions, right? They are “just” animated?
Cheers
The direction is displayed and only the active ones.
Ahh, OK. Currently I didn’t get an values displayed. How are your items configured? I already tried to rename mine to the names from Widget as well as I changed Widget to reflect my Item Names.
You dont have to rename anything. Go to settings/pages. Click to the setting symbol of the wiget and choose configure cell. There are boxes to pick your items.
OK, missed the option to “Set_Props”
But … I configured all of them and most are shown right away. Once I saved it I did get confirmation “Widget updated”. Once I left widget and go back into it, configuration is lost and nothing is shown up
Changes to other widgets are working, and also if I add tags to this widget, it’s working as well. just not to “set” Props.
I dont realy know the problem, but you have to save at two different points. I mean this was my problem, too.
My widget on the overview page shows the input power from net and the power of the PV panels but all the animated arrows are missing. In the Set widget props page the parameters are in German so I wonder whether anybody could translate what they mean. I tried with Google translator but translations are really bad so I’m not quite sure what they mean.
Netzeinspeisung = the electricity that goes from your house to the energy supplier
Netzbezug = the electricity you get from the energy supplier
Gesamtverbrauch = the total consumption of your house
Batterieleistung = the current flowing to/from the battery (charging/discharging)
Battery state of charge in percent
Great, this helps a lot. I have an electricity meter (ABB) which measures electricity flow in both directions so when it gives negative power it means that I’m exporting electricity. Now I’m wondering whether I would need a new Item for Netzeinspeisung which would be 0 when importing electricity and positive value when exporting. I guess Gesamtverbrauch is the sum of Netzbezug and PV Leistung.
As I mentioned in my previous post the animated arrows are missing. I don’t have batteries so I didn’t put anything for Batterieleistung but the widget on my overview page shows NaN for the battery so I wonder how to eliminate this. I guess I could delete the code for batterie.
Network reference can also be negative, at least that’s how it works for me. All values that you do not use should be assigned a dummy item which has the value 0.
Simply removing values is not so easy because there are some dependencies.
I also had to adjust the widget because I don’t have a total consumption and it’s just too big for my tablet
OK, many thanks for the info. I’ll need to do more testing then.
I have to say this widget is really awesome. Only small issue is the battery icon which I would like to get rid of. I have cropped the original icons so now the arrows are closer to the icons. Animations for the arrows are working for me but they don’t show up in the static screen capture. PV power is still pretty low because it is early morning here.
Then simply delete this area, it’s pretty much at the end
- component: oh-link
config:
iconColor: red
iconF7: battery_0
iconSize: 33px
style:
font-size: 25px
font-weight: bold
white-space: nowrap
text: =items[props.batterylevel].state
visible: '=(Number.parseFloat(items[props.batterylevel].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.batterylevel].state
visible: '=(Number.parseFloat(items[props.batterylevel].state.split(" ")[0]) >= 10 && Number.parseFloat(items[props.batterylevel].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.batterylevel].state
visible: '=(Number.parseFloat(items[props.batterylevel].state.split(" ")[0]) >= 75) ? true : false'
OK, many thanks. Yes, now the battery icon disappeared from the widget.
A note for use with Safari:
Safari needs a defined width and height for the SVG animation. auto does not work.
like this:
...
- component: f7-row
config:
preserveAspectRatio: xMidYMid slice
style:
height: 100px
width: 100px
tag: svg
viewBox: 0 0 100 100
xmlns: http://www.w3.org/2000/svg
...
wow, very good icons. Is it possible to create a windmill-icon in the same style? That would be great!
Very cool widget!
I also don’t have a battery and thus I changed the code to:
uid: SMA_widget
tags: []
props:
parameters:
- context: item
label: Netzeinspeisung
name: netzeinspeisung
required: true
type: TEXT
- context: item
label: Netzbezug
name: netzbezug
required: true
type: TEXT
- context: item
label: Gesamtverbrauch
name: gesamtverbrauch
required: true
type: TEXT
- context: item
label: PV Leistung
name: pv_leistung
required: true
type: TEXT
parameterGroups: []
timestamp: Apr 22, 2022, 6:08:33 PM
component: f7-card
config:
class:
- display-flex
- flex-direction-column
- align-items-center
style:
height: 383px
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_grid_2
- component: Label
config:
style:
color: red
font-size: 25px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: =items[props.netzbezug].displayState
visible: '=(Number.parseFloat(items[props.netzeinspeisung].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: =items[props.netzeinspeisung].displayState
visible: '=(Number.parseFloat(items[props.netzeinspeisung].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: Label
config:
style:
font-size: 25px
font-weight: bold
text-align: center
width: 100px
text: =items[props.pv_leistung].displayState
- 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: '=(Number.parseFloat(items[props.batterieleistung].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.batterieleistung].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.netzeinspeisung].state.split(" ")[0]) > 0 && Number.parseFloat(items[props.netzbezug].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.netzeinspeisung].state.split(" ")[0]) > 0 && Number.parseFloat(items[props.netzbezug].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.pv_leistung].state.split(" ")[0]) - (Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) + Math.abs(Number.parseFloat(items[props.batterieleistung].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.pv_leistung].state.split(" ")[0]) - (Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) + Math.abs(Number.parseFloat(items[props.batterieleistung].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.netzbezug].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.netzbezug].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.batterieleistung].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.batterieleistung].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: =items[props.gesamtverbrauch].displayState
On my setup the energy flow from PV to consumers is not shown:
Should that work on setups with battery?
Thanks
Marco
I have modified the original code slightly:
uid: SMA_widget
tags: []
props:
parameters:
- context: item
label: Netzeinspeisung
name: netzeinspeisung
required: true
type: TEXT
- context: item
label: Netzbezug
name: netzbezug
required: true
type: TEXT
- context: item
label: Gesamtverbrauch
name: gesamtverbrauch
required: true
type: TEXT
- context: item
label: PV Leistung
name: pv_leistung
required: true
type: TEXT
- context: item
label: Batterieleistung
name: batterieleistung
required: true
type: TEXT
- context: item
label: Batterie Ladezustand
name: batterylevel
required: true
type: TEXT
parameterGroups: []
timestamp: Mar 22, 2022, 7:33:12 PM
component: f7-card
config:
class:
- display-flex
- flex-direction-column
- align-items-center
style:
height: 383px
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_grid_2
- component: Label
config:
style:
color: red
font-size: 20px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: =items[props.netzbezug].displayState
visible: '=(Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) == 0) ? true : false'
- component: Label
config:
style:
color: green
font-size: 20px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: =items[props.netzeinspeisung].displayState
visible: '=(Number.parseFloat(items[props.netzeinspeisung].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: Label
config:
style:
color: green
font-size: 20px
font-weight: bold
text-align: center
width: 100px
text: =items[props.pv_leistung].displayState
- component: oh-icon
config:
height: 110px
icon: sma_pv_2
style:
margin-top: -5px
- 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.batterieleistung].state.split(" ")[0]) < 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 4
style:
stroke-width: 4
tag: circle
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.batterieleistung].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(22, 160, 133, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) > 0 && Number.parseFloat(items[props.netzbezug].state.split(" ")[0]) == 0) ? true : false'
- component: f7-row
config:
fill: rgba(22, 160, 133, 0.8)
r: 4
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) > 0 && Number.parseFloat(items[props.netzbezug].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(22, 160, 133, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.pv_leistung].state.split(" ")[0]) - (Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) + Math.abs(Number.parseFloat(items[props.batterieleistung].state.split(" ")[0]))) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(22, 160, 133, 0.8)
r: 4
strokeWidth: 2
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.pv_leistung].state.split(" ")[0]) - (Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) + Math.abs(Number.parseFloat(items[props.batterieleistung].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(255, 0, 0, 0.8)
stroke-width: 2
tag: path
vector-effect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.netzbezug].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(255, 0, 0, 0.8)
r: 4
strokeWidth: 5
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.netzbezug].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.batterieleistung].state.split(" ")[0]) > 0) ? true : false'
- component: f7-row
config:
fill: rgba(100, 150, 200, 0.8)
r: 4
strokeWidth: 10
tag: circle
vectorEffect: non-scaling-stroke
visible: '=(Number.parseFloat(items[props.batterieleistung].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: 20px
font-weight: bold
margin-top: -10px
text-align: center
width: 100px
text: =items[props.gesamtverbrauch].displayState
- 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: {}
And the output is:
Basically I have changed the color of the animations. Perhaps I should use same unit for all the numbers.
I have to say this is really cool widget.