Seite 1 von 2

Potenzrechnen mit -Potenz. Pool Steuerung Aktiv Chlor

Verfasst: 22. Jul 2021 18:38
von Boxana
Hollo,
ich möchte in einr Rule gerne 10^-8 rechnen.

Ich rechne

1/10^8

Code: Alles auswählen

// Aktivchlor (mg/l HOCl) = "freies Chlor (DPD No.1) Aktivchlor (mg/l HOCl)" / (1 + [(0,0567 x T) + 1,476] x 10-8 / 10-pH)


rule "Rechnen"

when
    Item Pool_fCL changed
then
    //10^-8

    var  basis1 = 10
    var  exp1 = 8
    var  result1  = 1

    while (exp1 > 0)
        {
            result1 = result1 * basis1
            exp1 = exp1 - 1
            }
        result1 = 1 / result1 

        Pool_HOCl.postUpdate(result1)
end

leider ist das ergebniss immer 0

würde mich über hielfe freuen.

Gruss Christian

Re: Potenzrechnen mit - potenz

Verfasst: 22. Jul 2021 19:36
von Boxana
Habe de fehler glaube ich gefunden:
rule "Rechnen"

when
Item Pool_fCL changed
then
//10^-8

var Number basis1 = 10
var Number exp1 = 8
var Number result1 = 1

while (exp1 > 0)
{
result1 = result1 * basis1
exp1 = exp1 - 1
}

result1 = 1 / result1


Pool_HOCl.postUpdate(result1)
end
so geht es :-)

Re: Potenzrechnen mit - potenz

Verfasst: 22. Jul 2021 22:11
von peter-pan
Wie wär's mit "Math.pow" ?

Code: Alles auswählen

rule "test Potenz"
when
    Item Dummy_4 changed to ON
then
    

    var Double basis1 = 10.0
    var Double exp1 = 8.0
    var Number result1 = 1

    // mit Math.pow
    val potenz = Math.pow(basis1,exp1)
    logInfo("potenz","Potenz: {} ", potenz) 

    // mit While-Schleife
    while (exp1 > 0)
    {
    result1 = result1 * basis1
    exp1 = exp1 - 1
    }
    
    result1 = 1 / result1
   logInfo("potenz","Result1: {} ", result1)  
end

Re: Potenzrechnen mit - potenz

Verfasst: 23. Jul 2021 00:01
von udo1toni
Insbesondere sollte Math::pow(basis,exponent) mit beliebigen Dezimalzahlen für Basis und Exponent zurecht kommen.

Re: Potenzrechnen mit - potenz

Verfasst: 24. Jul 2021 14:17
von Boxana
Ich versuche euren vorschlag umzusetzen was auch im grunde funktioniert. Dafür ersteinmal Danke.
Ich weiss nicht wie ich es richtig machen muss wenn ich das Item "Pool_pH_wert" übereben möchte.

Auszug aus Items datei

Code: Alles auswählen

Number Pool_pH_wert     "Pool ph wert [%.2f (ph)]"  {channel="mqtt:topic:MyMQTTBroker:POOL_Steuerung:Pool_pH_wert"}
auserdem muss dem wert ein - vorangestellt werden.
also ( - Pool_pH_wert )

Code: Alles auswählen

rule "Pool Aktiv Chlor berechnen"

when
    Item Pool_fCL changed or Item Pool_CYA changed
then
//erste Potenz
    var Double basis1 = 10.0
    var Double exp1 = -8.0
//zweite Potenz
    var Double basis2 = 10.0
    var Double exp2 =  Pool_pH_wert.state as Number
 
//  erste Potenz / zweite Potenz
    val potenz = Math.pow(basis1,exp1) / Math.pow(basis2,exp2)
    logInfo("potenz","Potenz: {} ", potenz)
    end
volgender Fehler kommt im log:

==> /var/log/openhab/openhab.log <==
2021-07-24 15:32:37.338 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.DoubleExtensions.operator_minus(java.lang.Double) on instance: null in test

Re: Potenzrechnen mit - potenz

Verfasst: 24. Jul 2021 16:15
von peter-pan
Ich hab deine Regel mal "nachgebaut". Ich kenne zwar die einzelnen Wert nicht, aber eine Fehlermeldung bekomme ich auch nicht.
Die Regel:

Code: Alles auswählen

rule "Pool Aktiv Chlor berechnen"

when
    Item Dummy_4 changed to ON

//    Item Pool_fCL changed or Item Pool_CYA changed
then
//erste Potenz
    var Double basis1 = 10.0
    var Double exp1 = -8.0
//zweite Potenz
    var Double basis2 = 10.0
//    var Double exp2 =  Pool_pH_wert.state as Number
    var Double exp2 = (Double.parseDouble(Moon_illumination.state.toString))*-1
    logInfo("potenz1", "Exponent 2: {}  Ursprungswert {} ", exp2, Moon_illumination.state.toString)
 
//  erste Potenz / zweite Potenz
    val potenz = Math.pow(basis1,exp1) / Math.pow(basis2,exp2)
    logInfo("potenz","Potenz: {} ", potenz)
    end
und das Ergebnis im Logger:

Code: Alles auswählen

2021-07-24 16:07:17.465 [INFO ] [rg.openhab.core.model.script.potenz1] - Exponent 2: -99.68318750361067  Ursprungswert 99.68318750361067 
2021-07-24 16:07:17.471 [INFO ] [org.openhab.core.model.script.potenz] - Potenz: 4.821559201466713E91 
Für das Item habe ich (näherungsweise) irgendein Item aus meinem Set genommen:

Code: Alles auswählen

Number Moon_illumination   "Mondhelligkeit"  <moon> (gAstro)  ["Point"]    {channel="astro:moon:local:phase#illumination"}
Das Vorzeichen habe ich einfach durch Multiplikation mit "-1" umgewandelt, wie man im Log sehen kann.

Was ich geändert habe ist die Umwandlung des Number-Wertes in einen Double-Wert. Das könnte eventuell der Grund für die Fehlermeldung sein.


Edit:
Alternative sollte auch diese Möglichkeit gehen:

Code: Alles auswählen

    var Double exp2 = (Moon_illumination.state as Number).doubleValue * -1

Re: Potenzrechnen mit - potenz

Verfasst: 24. Jul 2021 17:02
von Boxana
Danke das du dir so viel zeit nimmst.

Mein ziel ist es, das wasser im Pool automatisch mit sonden zu messen. Habe es schon grob fertig. Ich sende die daten mit MQTT von einem Arduino an Openhab was auch schon teilweise geht. Habe noch keine Sonde sonder setzt die werte von hand. Aber es wird richtig übertragen ;-)

Auserdem messe ich regelmässig zur kontrolle mit einem Photometer das Freie Chlor. Diesen Wert trage ich erseinmal von hand in der Sidmap ein.
Da es aber auf das Aktive Chlor ankommt und dieser wert nicht gemessen werden kann muss er errechnet werden. Dann komt noch der wert der Cyanusäure ins spiel. Die Puffert je nach höhe mehr oder weniger (nicht linear) das Freie Chlor.

Wenn ich jetzt den gemessenen wert eingebe errechnet die rule es jetzt im moment richtig und ich kann jetzt ein skript bauen was dann einmal am tag den wert mit dem sollwert vergleicht und nach bedarf mit einer dosirpumpe nach dosiert. Natürlich mit sicherungen das sie nicht dosiert wenn ich mal keinen neuen wert habe.
hier das script was richtig rechnet.

Code: Alles auswählen

// Die Formel um Aktivchlor (mg/l HOCl) zu errechen = freies Chlor (DPD No.1) Aktivchlor (mg/l HOCl) / (1 + [(0,0567 x T) + 1,476] x 10-8 / 10-pH)


rule "Rechnen"

when
    Item Pool_fCL changed or Item Pool_CYA changed
then
    var Number CYA_Puffer = 18   // Default Wert, falls nichts im Item steht
    //hier werden die Prozente für die Cyanusäure übergeben. Damit kann ermittelt werden wieviel Chlor noch frei ungepuffert zur verfügung gestellt wierd. Habe nur einen CAY Wert bis 50 ppm 
        //eingepflegt da ich in so hoch nicht kommen lasse.

    switch(Pool_CYA.state) {
        case  0: CYA_Puffer=0.955
        case  1: CYA_Puffer=0.924
        case  2: CYA_Puffer=0.903
        case  3: CYA_Puffer=0.8707298701
        case  4: CYA_Puffer=0.8372402597
        case  5: CYA_Puffer=0.8204954545
        case  6: CYA_Puffer=0.7870058442
        case  7: CYA_Puffer=0.770261039
        case  8: CYA_Puffer=0.7367714286
        case  9: CYA_Puffer=0.7200266234
        case 10: CYA_Puffer=0.7032818182
        case 11: CYA_Puffer=0.686537013
        case 12: CYA_Puffer=0.6530474026
        case 13: CYA_Puffer=0.6363025974
        case 14: CYA_Puffer=0.6195577922
        case 15: CYA_Puffer=0.602812987
        case 16: CYA_Puffer=0.5860681818
        case 17: CYA_Puffer=0.5693233766
        case 18: CYA_Puffer=0.5525785714
        case 19: CYA_Puffer=0.5358337662
        case 20: CYA_Puffer=0.519088961
        case 21: CYA_Puffer=0.5023441558
        case 22: CYA_Puffer=0.4855993506
        case 23: CYA_Puffer=0.4688545455
        case 24: CYA_Puffer=0.4688545455
        case 25: CYA_Puffer=0.4521097403
        case 26: CYA_Puffer=0.4353649351
        case 27: CYA_Puffer=0.4353649351
        case 28: CYA_Puffer=0.4186201299
        case 29: CYA_Puffer=0.4018753247
        case 30: CYA_Puffer=0.4018753247
        case 31: CYA_Puffer=0.3851305195
        case 32: CYA_Puffer=0.3683857143
        case 33: CYA_Puffer=0.3683857143
        case 34: CYA_Puffer=0.3516409091
        case 35: CYA_Puffer=0.3348961039
        case 36: CYA_Puffer=0.3348961039
        case 37: CYA_Puffer=0.3181512987
        case 38: CYA_Puffer=0.3181512987
        case 39: CYA_Puffer=0.3181512987
        case 40: CYA_Puffer=0.3181512987
        case 41: CYA_Puffer=0.3014064935
        case 42: CYA_Puffer=0.3014064935
        case 43: CYA_Puffer=0.2846616883
        case 44: CYA_Puffer=0.2846616883
        case 45: CYA_Puffer=0.2846616883
        case 46: CYA_Puffer=0.2679168831
        case 47: CYA_Puffer=0.2679168831
        case 48: CYA_Puffer=0.2679168831
        case 49: CYA_Puffer=0.2679168831
        case 50: CYA_Puffer=0.2679168831

        default: CYA_Puffer=1   // Default Wert, falls nichts im Item steht
    }






//
    //10^-8
    var Number  basis1 = 10
    var Number  exp1 = 8
    var Number  result1  = 1

    while (exp1 > 0)
        {
            result1 = result1 * basis1
            exp1 = exp1 - 1
            }
    result1 = 1 / result1   

    //10^-pH
    var Number  basis2 = 10
    var Number  exp2 = (Pool_pH_wert.state as Number)
    var Number  result2  = 1

    while (exp2 > 0)
        {
            result2 = result2 * basis2
            exp2 = exp2 - 1
            }
    result2 = 1 / result2   
    var Number  result3  = result1 / result2
  
        var Number  runde_klammer = 0.0567 * ( Pool_Temp.state as Number)
        var Number eckige_klammer = runde_klammer + 1.476  
        var Number expo_dividieren = eckige_klammer * result3 + 1
        var Number HOCl_Aktiv = (Pool_fCL.state as Number) / expo_dividieren
        HOCl_Aktiv = HOCl_Aktiv * CYA_Puffer



        Pool_HOCl.postUpdate(HOCl_Aktiv)
end
Die temperatur und der pH wert kommt auch vom Ardurino.

ich werde jetzt noch einmal mit deinem skript arbeiten da es ja doch um einiges kürzer ist.

Re: Potenzrechnen mit -Potenz. Pool Steuerung Aktiv Chlor

Verfasst: 25. Jul 2021 12:49
von Boxana
Hllao Peter Pan,
ich habe es jetzt nocheinmal mit deinem weg umgebaut und es ist jetzt um einiges küzer.

Wenn ich jetzt die der DPD No.1 messung aus dem Pool an Openhab übergebe ( im moment noch über Sidemap) habe ich den errechneten wert vom Aktiv wirksames Chlor. Damit lässt sich arbeiten.
Der wert ist der gleiche wie der ermittelte wert auf der webseite von https://www.pooldigital.de/shop/wissens ... erechnung/ mit dem vorteil das ich jetzt auch die Temperatur berücksichtige.
wär schön wenn du nocheinmal drüber schauen könntest aber es läuft so ohne Fehler.

Code: Alles auswählen

rule "Pool Aktiv Chlor berechnen"

when
    Item Pool_fCL changed or Item Pool_CYA changed

then
    //hier werden die Prozente für die Cyanusäure übergeben. Damit kann ermittelt werden wieviel Chlor noch frei ungepuffert zur verfügung gestellt wierd. Habe nur einen CAY Wert bis 50 ppm 
        //eingepflegt da ich in so hoch nicht kommen lasse.
    var Number CYA_Puffer = 1
    switch(Pool_CYA.state) {
        case  0: CYA_Puffer=0.955
        case  1: CYA_Puffer=0.924
        case  2: CYA_Puffer=0.903
        case  3: CYA_Puffer=0.8707298701
        case  4: CYA_Puffer=0.8372402597
        case  5: CYA_Puffer=0.8204954545
        case  6: CYA_Puffer=0.7870058442
        case  7: CYA_Puffer=0.770261039
        case  8: CYA_Puffer=0.7367714286
        case  9: CYA_Puffer=0.7200266234
        case 10: CYA_Puffer=0.7032818182
        case 11: CYA_Puffer=0.686537013
        case 12: CYA_Puffer=0.6530474026
        case 13: CYA_Puffer=0.6363025974
        case 14: CYA_Puffer=0.6195577922
        case 15: CYA_Puffer=0.602812987
        case 16: CYA_Puffer=0.5860681818
        case 17: CYA_Puffer=0.5693233766
        case 18: CYA_Puffer=0.5525785714
        case 19: CYA_Puffer=0.5358337662
        case 20: CYA_Puffer=0.519088961
        case 21: CYA_Puffer=0.5023441558
        case 22: CYA_Puffer=0.4855993506
        case 23: CYA_Puffer=0.4688545455
        case 24: CYA_Puffer=0.4688545455
        case 25: CYA_Puffer=0.4521097403
        case 26: CYA_Puffer=0.4353649351
        case 27: CYA_Puffer=0.4353649351
        case 28: CYA_Puffer=0.4186201299
        case 29: CYA_Puffer=0.4018753247
        case 30: CYA_Puffer=0.4018753247
        case 31: CYA_Puffer=0.3851305195
        case 32: CYA_Puffer=0.3683857143
        case 33: CYA_Puffer=0.3683857143
        case 34: CYA_Puffer=0.3516409091
        case 35: CYA_Puffer=0.3348961039
        case 36: CYA_Puffer=0.3348961039
        case 37: CYA_Puffer=0.3181512987
        case 38: CYA_Puffer=0.3181512987
        case 39: CYA_Puffer=0.3181512987
        case 40: CYA_Puffer=0.3181512987
        case 41: CYA_Puffer=0.3014064935
        case 42: CYA_Puffer=0.3014064935
        case 43: CYA_Puffer=0.2846616883
        case 44: CYA_Puffer=0.2846616883
        case 45: CYA_Puffer=0.2846616883
        case 46: CYA_Puffer=0.2679168831
        case 47: CYA_Puffer=0.2679168831
        case 48: CYA_Puffer=0.2679168831
        case 49: CYA_Puffer=0.2679168831
        case 50: CYA_Puffer=0.2679168831

        default: CYA_Puffer=1   // Default Wert, falls nichts im Item steht
    }
    logInfo("potenz","CYA_Puffer: {} ", CYA_Puffer)


//erste Potenz
    var Double basis1 = 10.0
    var Double exp1 = -8.0
//zweite Potenz
    var Double basis2 = 10.0
    var Double exp2 = (Double.parseDouble(Pool_pH_wert.state.toString))*-1
    logInfo("potenz1", "Exponent 2: {}  Ursprungswert {} ", exp2, Pool_pH_wert.state.toString)
 
//  erste Potenz / zweite Potenz
    val potenz = Math.pow(basis1,exp1) / Math.pow(basis2,exp2)
    logInfo("potenz","Potenz: {} ", potenz)

// runde klammer ausrechnen  1 + [(0,0567 x T) + 1,476] x 10-8 / 10-pH
    var Number  runde_klammer = 0.0567 * ( Pool_Temp.state as Number)
    logInfo("potenz","runde Klammer: {} ", runde_klammer)

// eckige klammer ausrechnen  1 + [(0,0567 x T) + 1,476] x 10-8 / 10-pH
    var Number eckige_klammer = runde_klammer + 1.476
    logInfo("potenz","eckige Klammer: {} ", eckige_klammer)

// ergebnis * (ergebnis aus bruch(Potenzen)) +1
    var Number expo_dividieren = eckige_klammer * potenz + 1
    logInfo("potenz","expo_dividieren: {} ", expo_dividieren)
    
// messergebnis der DPD No.1 aus dem Pool geteilt durch das bisherige Ergebniss    
    var Number HOCl_Aktiv = (Pool_fCL.state as Number) / expo_dividieren
    logInfo("potenz","HOCl_Aktiv: {} ", HOCl_Aktiv)

// jetzt noch den Cyanusäure gehalt berücksichtigen     
    HOCl_Aktiv = HOCl_Aktiv * CYA_Puffer
    logInfo("potenz","HOCl_Aktiv: {} ", HOCl_Aktiv)

// ergebniss an item übertragen    
    Pool_HOCl.postUpdate(HOCl_Aktiv)
    

    end

Re: Potenzrechnen mit -Potenz. Pool Steuerung Aktiv Chlor

Verfasst: 25. Jul 2021 14:04
von udo1toni
Tipp: Du kannst statt der switch-case Anweisung auch eine Hashmap nutzen, das geht schneller:

Code: Alles auswählen

import java.util.HashMap

val Hashmap<Number,Number> hmPuffer = newHashMap[ 0 -> 0.955,         1 -> 0.924,         2 -> 0.903,
                                                  3 -> 0.8707298701,  4 -> 0.8372402597,  5 -> 0.8204954545, 
                                                  6 -> 0.7870058442,  7 -> 0.770261039,   8 -> 0.7367714286, 
                                                  9 -> 0.7200266234, 10 -> 0.7032818182, 11 -> 0.686537013,
                                                 12 -> 0.6530474026, 13 -> 0.6363025974, 14 -> 0.6195577922,
                                                 15 -> 0.602812987,  16 -> 0.5860681818, 17 -> 0.5693233766,
                                                 18 -> 0.5525785714, 19 -> 0.5358337662, 20 -> 0.519088961,
                                                 21 -> 0.5023441558, 22 -> 0.4855993506, 23 -> 0.4688545455,
                                                 24 -> 0.4688545455, 25 -> 0.4521097403, 26 -> 0.4353649351,
                                                 27 -> 0.4353649351, 28 -> 0.4186201299, 29 -> 0.4018753247,
                                                 30 -> 0.4018753247, 31 -> 0.3851305195, 32 -> 0.3683857143,
                                                 33 -> 0.3683857143, 34 -> 0.3516409091, 35 -> 0.3348961039,
                                                 36 -> 0.3348961039, 37 -> 0.3181512987, 38 -> 0.3181512987,
                                                 39 -> 0.3181512987, 40 -> 0.3181512987, 41 -> 0.3014064935,
                                                 42 -> 0.3014064935, 43 -> 0.2846616883, 44 -> 0.2846616883,
                                                 45 -> 0.2846616883, 46 -> 0.2679168831, 47 -> 0.2679168831,
                                                 48 -> 0.2679168831, 49 -> 0.2679168831, 50 -> 0.2679168831 ]

rule "Pool Aktiv Chlor berechnen"
when
    Item Pool_fCL changed or Item Pool_CYA changed
then
    var Number CYA_Puffer = 1
    if(Pool_CYA.state instanceof Number)
        if((Pool_CYA.state as Number).intValue > -1 && (Pool_CYA.state as Number).intValue < 51) 
            CYA_Puffer = hmPuffer.get((Pool_CYA.state as Number).intValue)
    logInfo("potenz","CYA_Puffer: {} ", CYA_Puffer)
Rest des Codes kann gleich bleiben.

Ich gehe davon aus, dass Du die Zwischenwerte eher zum testen brauchst. Die Formel kannst Du direkt so verwenden, die DSL beherrscht die mathematischen Grundreglen (Punkt vor Strich, Klammern)

Re: Potenzrechnen mit -Potenz. Pool Steuerung Aktiv Chlor

Verfasst: 25. Jul 2021 14:21
von peter-pan
Boxana hat geschrieben: 25. Jul 2021 12:49 wär schön wenn du nocheinmal drüber schauen könntest aber es läuft so ohne Fehler.
Danke, aber ich habe gehofft, dass sich Udo noch einklinkt.Ich bin da eher nicht so der Mathematiker ;) . Und Udo hat es auch auf den Punkt gebracht.

Gruss - Peter