2 Number item Verbinden zu einem (neg pos Werte)

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
mad-mike
Beiträge: 488
Registriert: 6. Jan 2021 18:05
Answers: 3

2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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"}
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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
- OpenHab 2.4
#PWRUP

mad-mike
Beiträge: 488
Registriert: 6. Jan 2021 18:05
Answers: 3

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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.
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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 ?
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Harka
Beiträge: 487
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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

mad-mike
Beiträge: 488
Registriert: 6. Jan 2021 18:05
Answers: 3

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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'
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

Benutzeravatar
udo1toni
Beiträge: 15240
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

mad-mike
Beiträge: 488
Registriert: 6. Jan 2021 18:05
Answers: 3

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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... :oops:
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

Benutzeravatar
udo1toni
Beiträge: 15240
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: 2 Number item Verbinden zu einem (neg pos Werte)

Beitrag 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.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten