Seite 1 von 2
2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 7. Jun 2025 16:20
von mad-mike
Moin zusammen.
Ich möchte ein Dashboard für die Anzeige der Solaranlage zur Visualisierung nutzen.
für die Anzeige ist es elementar, das ich die Leistungs nutzung vom Akku als 1 Item habe welches Positiv, wie auch Negative Zahlen anzeigt.
Pos Wert = Akku Entladen
Neg Wert = Akku Laden
Die beiden Item liegen mir als Text file und kommen über Modbus rein.
Ich würde ein Item erstellen wollen, welcher dann akku_power heisst, oder so. und dieses soll gefüttert werden.
Geht das nur über eine Rule??
Und wie bekomme ich den Wert negativ angezeigt??
Danke und Gruss...
Code: Alles auswählen
Number Akku_watt "Akku Watt [%.1f W]" <flow> (gGrowatt) {channel="modbus:data:tcpBridge:inputPoller:Akku_watt:number"}
Number Akku_laden "Akku_laden [%.1f W]" <energy> (gGrowatt) {channel="modbus:data:tcpBridge:inputPoller:Akku_load:number"}
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 7. Jun 2025 20:26
von PeterA
Hi mad-mike,
endlich geht das Forum wieder wie toll!
Einen ähnlichen Usecase habe ich hier auch.
Von meinem Victron kommt das auch so ähnlich.
Akku wird geladen Wert positiv also >=0 und wenn entladen wird dann <=0 und mit negativem Vorzeichen.
Aber alles in einem Item.
Aber das ist letztendlich egal denn man kann ja in der UI mit
"visibility" und "labelcolor" usw Arbeiten.
Leider kann ich aktuell kein Code aus meiner Sitemap Posten
da ich unterwegs bin.
Aber im Prinzip kannst Du da genau definieren wann das Positive Item zu sehen und wann nicht usw.
Funktioniert sehr gut.
Gruß Peter
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 7. Jun 2025 22:27
von mad-mike
Aber alles in einem Item
Das brauche ich ja...
Leider ist es bei mir getrennt. 2 Item, 2 positive zahlen.
Kann aber bei der grafischen anzeige nur 1 Item für die Akku Leistung einstellen.
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 7. Jun 2025 23:01
von peter-pan
mad-mike hat geschrieben: ↑7. Jun 2025 16:20
Ich möchte ein Dashboard für die Anzeige der Solaranlage zur Visualisierung nutzen
Was ist denn das für ein Dashboard ? Und wie bringst du die OH-Werte da hinein ?
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 8. Jun 2025 06:49
von Harka
Moin,
Du kannst den einen Wert mittels Profil auch in eine negative Zahl umwandeln. Ich nutze nicht die Textkonfiguration aber [profile="system:hysteresis", inverted="true"] wäre mein erster Versuch. Anschließend akku_power als nummerisches Gruppen-Item anlegen, welches die Summe von seinen beiden Mitgliedern bildet.
Im Prinzip geht auch was über Transformation, aber da habe ich jetzt keine 100% saubere Lösung hinbekommen und eine Rule ist imho der deutlich einfachere Weg.
E: an Stelle des Profils kann auch eine einzeilige Transformation (Multiplikation mit -1) in Frage kommen
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 8. Jun 2025 19:49
von mad-mike
Ich habe etwas probiert, und gemacht und getan...
Also, es handelt sich um das SMA Widget wo man die Akku Leistung als item eingeben muss.
ich hab mal versucht das ganze Widget um ein Item zu erweitern.. Nun habe ich hier 2 Item, und versuche diese ganzen regel zu verstehen,
Code: Alles auswählen
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_pos
name: batterieleistung_pos
required: true
type: TEXT
- context: item
label: Batterieleistung_neg
name: batterieleistung_neg
required: true
type: TEXT
- context: item
label: Batterie Ladezustand
name: batterylevel
required: true
type: TEXT
parameterGroups: []
timestamp: May 19, 2023, 2:50:20 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_pos].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_pos].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_neg].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_neg].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_neg].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_neg].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
- 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.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'
- component: oh-icon
config:
height: 110px
icon: sma_battery_2
style:
margin-top: -20px
- component: Label
config:
style:
color: '=(Number.parseFloat(items[props.batterieleistung_pos].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.batterieleistung_pos].state.split("
")[0])) + ' ᵂ'
visible: '=(Number.parseFloat(items[props.batterieleistung_pos].state.split(" ")[0])
!== 0) ? true : false'
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 9. Jun 2025 00:00
von udo1toni
Darf ich hier einmal darauf hinweisen, dass die beiden Werte nicht in Items ankommen, sondern in Channels? Und wenn Du zwei Channels hast, welche jeweils einen positiven Wert oder 0 liefern, sollte es reichen, beide Channel mit einem Item zu verlinken. Der Trick besteht dann darin, jeweils ein Inline Script als Profile zu nutzen. Im einen Channel sorgt das Inline Script dafür, dass der Wert nur dann übernommen wird, wenn er größer 0 ist.
Im anderen Channel gilt das gleiche, allerdings wird der Wert vorher mit -1 multipliziert.
Wichtig für den Hinterkopf: Der Status wird immer als String übergeben, entsprechend muss man den Input evtl. per parse.float in eine Zahl umwandeln.
Ungetestet: DSL|if(parse.float(input)> 0 ) - parse.float(input) für den negativ-Wert.
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 11. Jun 2025 17:15
von mad-mike
Der Trick besteht dann darin, jeweils ein Inline Script als Profile zu nutzen.
Aber wie muss man dies doch gleich machen?
Macht man das über die Text files, oder über die UI??
Ich kann auch mit der Doku nichts anfangen...

Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 11. Jun 2025 20:51
von udo1toni
Inline -> Das Script wird direkt übergeben. Das Script ist kurz genug (siehe ungetestete Zeile)
Soweit ich weiß, kannst Du bei Modbus innerhalb des Channels keine Transformation durchführen, deshalb muss die Transformation im Profile erfolgen.
Wenn Du über die UI konfigurierst, wählst Du DSL als Scriptsprache aus und schreibst die Codezeile (mit Pipe) in das to Item Script Feld. Über eine Items-Datei sähe das so aus (ohne Gewähr):
Code: Alles auswählen
Number:Power AkkuLoad "Akku Leistung" {channel="inChannel"[profile="transform:DSL",toItemScript="|if(parse.float(input)> 0 ) - parse.float(input)"],
channel="outChannel"[profile="transform:DSL",toItemScript="|if(parse.float(input)> 0 ) parse.float(input)"],
unit="W", stateDescription=""[pattern="%.3f kW"]}
Die Umbrüche hier nur wegen der Lesbarkeit, natürlich kannst Du das formatieren wie es Dir beliebt.
Da modbus meines Wissens selbst keine Unit unterstützt, muss die angegebene Unit der gelieferten Unit entsprechen. Im Pattern kannst Du aber jede passende Unit verwenden, d.h. die Ausgabe sollte automatisch korrekt sein. Das Widget dürfte unit-aware sein, weil die meisten Bindings inzwischen eine Unit liefern.
Wahlweise könntest Du die beiden Scripte natürlich auch in Dateien speichern und diese angeben, aber da es ja nur eine Zeile ist und Du im Zweifel zwei Scripte benötigst, ist das etwas umständlich.
Re: 2 Number item Verbinden zu einem (neg pos Werte)
Verfasst: 14. Jun 2025 17:44
von mad-mike
Code: Alles auswählen
2025-06-14 17:33:21.133 [ERROR] [.module.script.profile.ScriptProfile] - Failed to process script '|if(parse.float(input)> 0 ) - parse.float(input)': if( ___ parse. ___ float(input)> 0 ) - ___ parse. ___ float(input)
1. The method float(String) is undefined for the type Duration; line 1, column 9, length 5
2. The method float(String) is undefined for the type Duration; line 1, column 35, length 5
3. Invalid number of arguments. The method parse(CharSequence) is not applicable without arguments; line 1, column 3, length 5
4. Invalid number of arguments. The method parse(CharSequence) is not applicable without arguments; line 1, column 29, length 5
2025-06-14 17:33:21.135 [ERROR] [.module.script.profile.ScriptProfile] - Failed to process script 'DSL|if("parse.float(input) > 0 ) - parse.float(input)"': Could not get script for UID 'DSL|if("parse.float(input) > 0 ) - parse.float(input)"'.
so ganz will das noch nicht
