Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von udo1toni »

peter-pan hat geschrieben: 9. Mär 2019 10:53 So ähnlich wie du es beschrieben hast gehe ich auch schon vor (in der while-Schleife), wobei ich allerdings nicht ganz so genau die Tageszeit, sondern nur den Tag (bin schon froh, dass ich überhaupt so weit gekommen bin) als solches vergleiche und dann das zugehörige indizierte(var itemindex) Item (Temp, Schnee, Regen) in das entsprechende Summenfeld (If-Clause 0 -5) für diesen Tag.
Da Du die berechneten Werte ja anschließend in Items schreibst, ist das ganze rumgeschiebe in Variablen eher unpraktisch. Ich hab das ja nun nicht komplett durchgespielt, aber ich denke, zusätzlich zu den 6 Zeilen Code kommen vielleicht nochmal 12 Zeilen dazu, um alle Werte über alle Tage zu berechnen. Die ganzen ifs und Variablen sind Balast.
P.S.: ich bin ja als Schwabe grundsätzlich nicht neugierig :lol: , aber arbeitest du in einem Rechenzentrum, oder womöglich bei der ESA ?
Ganz so hoch hinaus wollte ich nie :lol: Ich arbeite beim Hörfunk als Schaltmeister, das heißt, ich kümmere mich um die Anbindung der Studios, Übertragungswagen, Korrespondenten usw. Daher auch mein Nickname, Udo ein Tontechniker ;)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von peter-pan »

Ich habe wieder etwas an meiner Regel gearbeitet und so den Code um einiges (fast 100 Zeilen) reduzieren können. Wenn ich die LogInfos noch rausschmeisse, sind es wahrscheinlich noch mal 50 -60 Zeilen weniger. Die hab ich aber deshalb drin, um wieder Anhaltspunkte zu haben, wenn ein Fehler beim Testen von Änderungen auftreten sollte.
Ich habe jetzt das meiste über HashMaps zwischengespeichert und an Stelle der vielen If-Klauseln eine State-Machine (switch/Case) eingesetzt, das hat den eigentlichen Prozessteil um einiges reduziert.

Das Ganze sieht jetzt so aus:

Code: Alles auswählen

// Idee für neuen Ansatz von Udo:   https://openhabforum.de/viewtopic.php?f=15&t=1308   // Optimierungsansatz von Udo
import org.eclipse.smarthome.model.script.ScriptServiceUtil
import java.util.Map
   var logCount = 8               // Interval Variable for displaying Logmessages in Logger (frontail)
   val rulename = "owm-weather" 

rule "WetterAufbereitung"
  when
   Item owmTriggerSwitch received command ON  or
   Item localLastMeasurement changed
  then
   var Number logYes1 = 0  // it's no boolean - I know ;)
   var Number logYes2 = 0  // it's no boolean - I know ;)

   var tmp_timestamp = new DateTime().toString("yyMMdd")
   var tmp_day = new DateTime(localLastMeasurement.state.toString)
//---------------------------------------  Array List  --------------------------------------------------------------------------------------
   var vCounter_day = 0      // Index for Day
   var day0 = new DateTime(tmp_day).toString("yyMMdd")
   var day1 = new DateTime(tmp_day).plusDays(1).toString("yyMMdd")
   var day2 = new DateTime(tmp_day).plusDays(2).toString("yyMMdd")
   var day3 = new DateTime(tmp_day).plusDays(3).toString("yyMMdd")
   var day4 = new DateTime(tmp_day).plusDays(4).toString("yyMMdd")
   var day5 = new DateTime(tmp_day).plusDays(5).toString("yyMMdd")

   var temp_day = newArrayList(
          day0,
          day1,
          day2,
          day3,
          day4,
          day5
)
//------------------------------------ End Array List ----------------------------------------------------------------------------------------
   //++++ Temperature Results for the days
   var vCount_temp_day = "day"+vCounter_day
   if( logCount >= 8 ) logInfo ("owm-weather", "Starts" + " + Trigger " + triggeringItem + " + vCount_temp_day" + vCount_temp_day)  

var Map<String, Number> mSumTempDay = newHashMap
    mSumTempDay.put("day0", 0)
    mSumTempDay.put("day1", 0)
    mSumTempDay.put("day2", 0)
    mSumTempDay.put("day3", 0)
    mSumTempDay.put("day4", 0)
    mSumTempDay.put("day5", 0)

var Map<String, Number> mAvgTempDay = newHashMap
    mAvgTempDay.put("day0", 0)
    mAvgTempDay.put("day1", 0)
    mAvgTempDay.put("day2", 0)
    mAvgTempDay.put("day3", 0)
    mAvgTempDay.put("day4", 0)
    mAvgTempDay.put("day5", 0)

var Map<String, Number> mMinTempDay = newHashMap
    mMinTempDay.put("day0", 999.9)
    mMinTempDay.put("day1", 999.9)
    mMinTempDay.put("day2", 999.9)
    mMinTempDay.put("day3", 999.9)
    mMinTempDay.put("day4", 999.9)
    mMinTempDay.put("day5", 999.9)

var Map<String, Number> mMaxTempDay = newHashMap
    mMaxTempDay.put("day0", -999.9)
    mMaxTempDay.put("day1", -999.9)
    mMaxTempDay.put("day2", -999.9)
    mMaxTempDay.put("day3", -999.9)
    mMaxTempDay.put("day4", -999.9)
    mMaxTempDay.put("day5", -999.9)

   //++++ Rain Results for the days
var Map<String, Number> mSumRainDay = newHashMap
    mSumRainDay.put("day0", 0)
    mSumRainDay.put("day1", 0)
    mSumRainDay.put("day2", 0)
    mSumRainDay.put("day3", 0)
    mSumRainDay.put("day4", 0)
    mSumRainDay.put("day5", 0)
   //++++ Snow Results for the days
var Map<String, Number> mSumSnowDay = newHashMap
    mSumSnowDay.put("day0", 0)
    mSumSnowDay.put("day1", 0)
    mSumSnowDay.put("day2", 0)
    mSumSnowDay.put("day3", 0)
    mSumSnowDay.put("day4", 0)
    mSumSnowDay.put("day5", 0)
       if (logYes1 == 1) logInfo (rulename, "DebugPoint xz: Before Initial If " )
   //------------------------------------------------------------------------------------------------------------------------------------------
   //++++ initial variables for the "while"-loop ++++
   var itemindex = 3        // item index initial
   var itemincrement  = 3   // item step
   val imin = 3             // index minimum
   val imax = 120           // index maximum
   var count_day0 = 0
   var count_day1 = 0
   var count_day2 = 0
   var count_day3 = 0
   var count_day4 = 0
   var count_day5 = 0
   var Number min = 0
   var Number max = 0
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++             Processing              ++++++++++++++++++++++++++++++++++++++++++++++++++
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  while ((itemindex >=imin) && (itemindex <=imax))     //  ++++ Reduce itemindex for testing, when working it is 120 (imax) or less as in Thing-Parameter declared--> forecastHours=xxx <-- ++++
  {
   //++++ Pointer-adresses for the dynamically generated items                                                                                        ***thx to @5iver and @rlkoshak for help***
   var GenericItem tempItemTimestamp   = ScriptServiceUtil.getItemRegistry.getItem("localHourlyForecast"+itemindex+"Timestamp")   as  GenericItem  // ***thx to @5iver ***
   var GenericItem tempItemTemperature = ScriptServiceUtil.getItemRegistry.getItem("localHourlyForecast"+itemindex+"Temperature") as  GenericItem  // ***thx to @5iver ***
   var GenericItem tempItemRainVolume  = ScriptServiceUtil.getItemRegistry.getItem("localHourlyForecast"+itemindex+"RainVolume")  as  GenericItem  // ***thx to @5iver ***
   var GenericItem tempItemSnowVolume  = ScriptServiceUtil.getItemRegistry.getItem("localHourlyForecast"+itemindex+"SnowVolume")  as  GenericItem  // ***thx to @5iver ***
   tmp_timestamp = new DateTime(tempItemTimestamp.state.toString).toString("yyMMdd") // create temporarily timestamp as needed -yyMMdd- current from GenericItem
   if ((tempItemTimestamp === null) || (tempItemTemperature === null) || (tempItemRainVolume === null) || (tempItemSnowVolume === null)) {
        if (logYes1 == 1) logInfo (rulename, "DebugPoint xx: tempItemTimestamp is null - Abbruch")
        return;
   }
   if (logYes1 == 1) logInfo (rulename, "DebugPoint yx:  Initial If" + tempItemTimestamp)
   //+++++++++++++++++++++++++++++++++ Outer If-Clause  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   if (tempItemTimestamp.state instanceof DateTimeType && (itemindex <=imax) && tempItemTemperature.state instanceof Number && 
       tempItemRainVolume.state instanceof Number && tempItemSnowVolume.state instanceof Number) {
       itemindex = itemindex + itemincrement                                             // increase counter
       if (logYes1 == 1)  logInfo (rulename, "DebugPoint yy:  Initial If itemindex: {} itemincrement: {} ", itemindex, itemincrement)

     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     //++++++++++++++++++++++++++++                 Day 0 - 5           ++++++++++++++++++++++++++++++++++++++++++++++++++
     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        switch(tmp_timestamp) {
          case temp_day.get(0): {
                                 vCount_temp_day = "day0"
                                 vCounter_day = 0               
                                 count_day0 = count_day0 + 1
                                 if (logYes1 == 1)  logInfo(rulename,"Zeitstempel {} vCount_temp_day {}  test {} ", tmp_timestamp, temp_day.get(vCounter_day), vCount_temp_day  )  
          }
          case temp_day.get(1): {
                                 vCount_temp_day = "day1"
                                 vCounter_day =1               
                                 count_day1 = count_day1 + 1
                                 if (logYes1 == 1)  logInfo(rulename,"Zeitstempel {} vCount_temp_day {}  test {} ", tmp_timestamp, temp_day.get(vCounter_day), vCount_temp_day  )  
          }
          case temp_day.get(2): {
                                 vCount_temp_day = "day2"
                                 vCounter_day =2               
                                 if (logYes1 == 1) logInfo(rulename,"Zeitstempel {} Count_Day2 {}  test {} ", tmp_timestamp, temp_day.get(vCounter_day) )  
                                 count_day2 = count_day2 + 1
          }
          case temp_day.get(3): {
                                 vCount_temp_day = "day3"
                                 vCounter_day =3               
                                 if (logYes1 == 1)  logInfo(rulename,"Zeitstempel {} Count_Day3 {}  test {} ", tmp_timestamp, temp_day.get(vCounter_day) )  
                                 count_day3 = count_day3 + 1
          }
          case temp_day.get(4): {
                                 vCount_temp_day = "day4"
                                 vCounter_day =4               
                                 if (logYes1 == 1)  logInfo(rulename,"Zeitstempel {} Count_Day4 {}  test {} ", tmp_timestamp, temp_day.get(vCounter_day) )  
                                 count_day4 = count_day4 + 1
          }
          case temp_day.get(5): {
                                 vCount_temp_day = "day5"
                                 vCounter_day =5               
                                 if (logYes1 == 1)  logInfo(rulename,"Zeitstempel {} Count_Day5 {}  test {} ", tmp_timestamp, temp_day.get(vCounter_day), temp_day.get(5))  
                                 count_day5 = count_day5 + 1
          }
          default  : {
                    logInfo("Rle","Nichts passiert in Case")
          }
        }
        //----------------------------------------------------------------------------------------------------------------------------
       if (logYes1 == 1) logInfo(rulename,"Zeitstempel {} Count_Day ist {}  test {} vCount_temp_day{}" , tmp_timestamp, temp_day.get(vCounter_day), vCount_temp_day )  // test

   } else {
            return;  // test
   }//end of outer If-Clause
   if (logYes1 == 1)  logInfo (rulename, "DebugPoint 50  after outer If")
                                 mSumTempDay.put(vCount_temp_day, mSumTempDay.get(vCount_temp_day) + tempItemTemperature.getStateAs(DecimalType))
                                 //++++++++++++++++ Temperature Minimum of the day +++++++++++++++++++++++++++++++++++++++++++++++++
                                 
                                  min = tempItemTemperature.getStateAs(DecimalType)
                                  if (mMinTempDay.get(vCount_temp_day) > min) {
                                      mMinTempDay.put(vCount_temp_day,tempItemTemperature.getStateAs(DecimalType))
                                  }
                                  //+++++++++++++++ Temperature Maximum of the day +++++++++++++++++++++++++++++++++++++++++++++++++
                                  max = tempItemTemperature.getStateAs(DecimalType)
                                  if (mMaxTempDay.get(vCount_temp_day) < max) {
                                      mMaxTempDay.put(vCount_temp_day,tempItemTemperature.getStateAs(DecimalType)) 
                                  }
                                  //+++++++++++++++ Rain Sum of the day +++++++++++++++++++++++++++++++++++++++++++++++++
                                 mSumRainDay.put(vCount_temp_day, mSumRainDay.get(vCount_temp_day) + tempItemRainVolume.getStateAs(DecimalType))
                                   //+++++++++++++++ Snow Sum of the day +++++++++++++++++++++++++++++++++++++++++++++++++
                                 mSumSnowDay.put(vCount_temp_day, mSumSnowDay.get(vCount_temp_day) + tempItemSnowVolume.getStateAs(DecimalType))

   }  // End of while
   if (logYes2 == 2)  logInfo (rulename, "DebugPoint 55  after While")

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   //++++++++++++++++++ Check Division by zero , calculate Average and update owm.items ++++++++++++++++++++++++++++
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//   if (mSumTempDay.get("day0") != 0 && count_day0 != 0) avg_temp_day0 = mSumTempDay.get("day0") / count_day0
   if (mSumTempDay.get("day0") != 0 && count_day0 != 0) localDay0TemperatureAverage.postUpdate(mSumTempDay.get("day0") / count_day0) else localDay0TemperatureAverage.postUpdate(0)
   if (mSumTempDay.get("day1") != 0 && count_day1 != 0) localDay1TemperatureAverage.postUpdate(mSumTempDay.get("day1") / count_day1) else localDay1TemperatureAverage.postUpdate(0)
   if (mSumTempDay.get("day2") != 0 && count_day2 != 0) localDay2TemperatureAverage.postUpdate(mSumTempDay.get("day2") / count_day2) else localDay2TemperatureAverage.postUpdate(0)
   if (mSumTempDay.get("day3") != 0 && count_day3 != 0) localDay3TemperatureAverage.postUpdate(mSumTempDay.get("day3") / count_day3) else localDay3TemperatureAverage.postUpdate(0)
   if (mSumTempDay.get("day4") != 0 && count_day4 != 0) localDay4TemperatureAverage.postUpdate(mSumTempDay.get("day4") / count_day4) else localDay4TemperatureAverage.postUpdate(0)
   if (mSumTempDay.get("day5") != 0 && count_day5 != 0) localDay5TemperatureAverage.postUpdate(mSumTempDay.get("day5") / count_day5) else localDay5TemperatureAverage.postUpdate(0)
   if (logYes2 == 2)  logInfo (rulename, "DebugPoint 60  after Check Division")
   //++++++++++++++++ Update Items in owm.items +++++++++++++++++++++++++++++++++++++++++++++++++
   localDay0RainTotal.postUpdate(mSumRainDay.get("day0"))
   localDay1RainTotal.postUpdate(mSumRainDay.get("day1"))
   localDay2RainTotal.postUpdate(mSumRainDay.get("day2"))
   localDay3RainTotal.postUpdate(mSumRainDay.get("day3"))
   localDay4RainTotal.postUpdate(mSumRainDay.get("day4"))
   localDay5RainTotal.postUpdate(mSumRainDay.get("day5"))
   localDay0SnowTotal.postUpdate(mSumSnowDay.get("day0"))
   localDay1SnowTotal.postUpdate(mSumSnowDay.get("day1"))
   localDay2SnowTotal.postUpdate(mSumSnowDay.get("day2"))
   localDay3SnowTotal.postUpdate(mSumSnowDay.get("day3"))
   localDay4SnowTotal.postUpdate(mSumSnowDay.get("day4"))
   localDay5SnowTotal.postUpdate(mSumSnowDay.get("day5"))
   if (logYes2 == 2)  logInfo (rulename, "DebugPoint 70  after Rain/Snow Update")
   //+++++++++++++++ Formatting and Updating Forecast StringItems in owm.items ++++++++++++++++++++
   localday0_format.postUpdate(new DateTime(tmp_day).toString("EE, dd.MMM"))
   var day0_format = new DateTime(tmp_day).toString("EE, dd.MMM")
   var day1_format = new DateTime(tmp_day).plusDays(1).toString("EE, dd.MMM")
   var day2_format = new DateTime(tmp_day).plusDays(2).toString("EE, dd.MMM")
   var day3_format = new DateTime(tmp_day).plusDays(3).toString("EE, dd.MMM")
   var day4_format = new DateTime(tmp_day).plusDays(4).toString("EE, dd.MMM")
   var day5_format = new DateTime(tmp_day).plusDays(5).toString("EE, dd.MMM")
   if (logYes2 == 2)  logInfo (rulename, "DebugPoint 80  after DateTime Formatting  minTemp 0:" + mMinTempDay.get("day0") + " maxTemp 0: " + mMaxTempDay.get("day0") )
//   //+++++++++++++++++  Concatenate for sitemap presentation ++++++++++++++++++++++++++++++++++++++++++++++++++++
   owmForecast_0Temp.postUpdate(day0_format + ": min/max/avg: " + String::format("%.1f",mMinTempDay.get("day0").floatValue()) + " / " + String::format("%.1f",mMaxTempDay.get("day0").floatValue()) + " / " + localDay0TemperatureAverage.state.format("%.1f").toString)
   owmForecast_1Temp.postUpdate(day1_format + ": min/max/avg: " + String::format("%.1f",mMinTempDay.get("day1").floatValue()) + " / " + String::format("%.1f",mMaxTempDay.get("day1").floatValue()) + " / " + localDay1TemperatureAverage.state.format("%.1f").toString)
   owmForecast_2Temp.postUpdate(day2_format + ": min/max/avg: " + String::format("%.1f",mMinTempDay.get("day2").floatValue()) + " / " + String::format("%.1f",mMaxTempDay.get("day2").floatValue()) + " / " + localDay2TemperatureAverage.state.format("%.1f").toString)
   owmForecast_3Temp.postUpdate(day3_format + ": min/max/avg: " + String::format("%.1f",mMinTempDay.get("day3").floatValue()) + " / " + String::format("%.1f",mMaxTempDay.get("day3").floatValue()) + " / " + localDay3TemperatureAverage.state.format("%.1f").toString)
   owmForecast_4Temp.postUpdate(day4_format + ": min/max/avg: " + String::format("%.1f",mMinTempDay.get("day4").floatValue()) + " / " + String::format("%.1f",mMaxTempDay.get("day4").floatValue()) + " / " + localDay4TemperatureAverage.state.format("%.1f").toString)
   owmForecast_5Temp.postUpdate(day5_format + ": min/max/avg: " + String::format("%.1f",mMinTempDay.get("day5").floatValue()) + " / " + String::format("%.1f",mMaxTempDay.get("day5").floatValue()) + " / " + localDay5TemperatureAverage.state.format("%.1f").toString)
   if (logYes2 == 2)   logInfo (rulename, "DebugPoint 100  Temp-update ")
   // Rain totals per Day    the multiplier is set to 1 as the values from OWM are for a 3-hours-period so no action is needed
   owmForecast_0Rain.postUpdate(day0_format + " " + String::format("%.1f",(mSumRainDay.get("day0") * 1)))
   owmForecast_1Rain.postUpdate(day1_format + " " + String::format("%.1f",(mSumRainDay.get("day1") * 1)))
   owmForecast_2Rain.postUpdate(day2_format + " " + String::format("%.1f",(mSumRainDay.get("day2") * 1)))
   owmForecast_3Rain.postUpdate(day3_format + " " + String::format("%.1f",(mSumRainDay.get("day3") * 1)))
   owmForecast_4Rain.postUpdate(day4_format + " " + String::format("%.1f",(mSumRainDay.get("day4") * 1)))
   owmForecast_5Rain.postUpdate(day5_format + " " + String::format("%.1f",(mSumRainDay.get("day5") * 1)))
   if (logYes2 == 2)  logInfo (rulename, "DebugPoint 110  Rain-update")
   // Snow totals per Day    the multiplier is set to 1 as the values from OWM are for a 3-hours-period so no action is needed
   owmForecast_0Snow.postUpdate(day0_format + " " + String::format("%.1f",(mSumSnowDay.get("day0") * 1)))
   owmForecast_1Snow.postUpdate(day1_format + " " + String::format("%.1f",(mSumSnowDay.get("day1") * 1)))
   owmForecast_2Snow.postUpdate(day2_format + " " + String::format("%.1f",(mSumSnowDay.get("day2") * 1)))
   owmForecast_3Snow.postUpdate(day3_format + " " + String::format("%.1f",(mSumSnowDay.get("day3") * 1)))
   owmForecast_4Snow.postUpdate(day4_format + " " + String::format("%.1f",(mSumSnowDay.get("day4") * 1)))
   owmForecast_5Snow.postUpdate(day5_format + " " + String::format("%.1f",(mSumSnowDay.get("day5") * 1)))
    if (logYes2 == 2)   logInfo (rulename, "DebugPoint 120  Snow-update")
   lastRuleRefresh.postUpdate(new DateTimeType())
   if( logCount >= 8 ) {
      logInfo (rulename, "End   of Process - 6a Aggregation daily Measures: " + logCount)    // log every fourth time - means two hours - to show that rule is alive
      logCount = 0
      logCount = logCount + 1
      //logInfo (rulename, "End   of Process - 6b Aggregation daily Measures: " + logCount) // Test Debug
   } 
   else {
      logCount = logCount +1
      //logInfo (rulename, "End   of Process - 7 Aggregation daily Measures: " + logCount) // Test Debug)
   }

end

Und es klappt ganz gut.

Als nächstes werde ich mich mal an die "GroupItem Methoden" heranwagen, so wie Udo, das weiter vorne beschrieben hat, aber irgendwie brauch ich da noch ein bisschen Zeit dazu (weil ich's nicht so richtig kapiere :oops: :?: ), bis mir ein :idea: aufgeht.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von peter-pan »

So, ich habe mich über's Wochenende auf den Hosenboden gesetzt und meine Wetter-Items neu angelegt, so wie das Udo weiter oben beschrieben hat. Das hat eine Weile gedauert (ca. 600 Items).
Dann habe ich meine Wetter-Rules "weggeschmissen" und das Ganze noch mal neu aufgebaut, wie Udo das weiter vorne beschrieben hat.
Was dabei raus gekommen ist, konnte ich erst gar nicht glauben. Meine erste Version hatte ca. 350 Zeilen, die zweite "nur" noch ca. 250. Und die jetzige Version hat gerade noch mal 80 und das Ganze ohne HashMaps, ArrayLists und Variablenherumgeschiebe.

Code: Alles auswählen

import org.eclipse.smarthome.model.script.ScriptServiceUtil
rule "owm forecasting"
  when
   Item Dummy4 changed to ON
   or Item owmTriggerSwitch received command ON  or
   Item localLastMeasurement_00 changed
   
  then

    val day  = -1 
    val day0 = 7 - (now.getHourOfDay / 3).intValue 
    val day1 = day0 + 8
    val day2 = day1 + 8
    val day3 = day2 + 8
    val day4 = day3 + 8
    val Number day5 = 40
    var counter = 0
    var daymin = 0
    var daymax = 0
    logInfo("forecasting","TriggerItem ist {}: / previous State: {} / new State {}: ", triggeringItem.name,previousState, newState)
  while (counter <= 5) {
    switch counter {
           case 0 :  {
                      daymin = day
                      daymax = day0
            }
           case 1 :  {
                      daymin = day0
                      daymax = day1
            }
           case 2 :  {
                      daymin = day1
                      daymax = day2
            }
           case 3 :  {
                      daymin = day2
                      daymax = day3
            }
           case 4 :  {
                      daymin = day3
                      daymax = day4
            }
           case 5 :  {
                      daymin = day4
                      daymax = day5
            }
    }
//  Temperature
//   Determine of relevant Items per day and sort them in ascending sequence by value for MIN/MAX detection
    var myTempItemList = gTemp.members.sortBy[state].filter[ i|Integer.parseInt(i.name.split("_").get(1)) > daymin && Integer.parseInt(i.name.split("_").get(1)) <= daymax ]
    var Number sumTemp = 0
    var avgTemp = 0
    myTempItemList.forEach[ g|sumTemp = sumTemp + ((g.state as Number ).floatValue) ]
    avgTemp = sumTemp / myTempItemList.size
    ScriptServiceUtil.getItemRegistry.getItem("localDayTempAVG_"+counter).postUpdate(avgTemp)                    // store daily average-temperature
    var Number vIndex = myTempItemList.size - 1                                                                  // Index for highest Temp-Value per day
    var minTemp = myTempItemList.get(0)                                                                          // lowest Temperture per day
    var maxTemp = myTempItemList.get(vIndex)                                                                     // highest Temperature per day
    ScriptServiceUtil.getItemRegistry.getItem("localDayTempMin_"+counter).postUpdate(minTemp.state)   
    ScriptServiceUtil.getItemRegistry.getItem("localDayTempMax_"+counter).postUpdate(maxTemp.state)   
//   Rain
    var myRainItemList = gRain.members.filter[ i|Integer.parseInt(i.name.split("_").get(1)) > daymin && Integer.parseInt(i.name.split("_").get(1)) <= daymax ]
    var Number sumRain = 0
    myRainItemList.forEach[ g|sumRain = sumRain + (((g.state as Number ).floatValue)*3) ]
    ScriptServiceUtil.getItemRegistry.getItem("localDayRainTotal_"+counter).postUpdate(sumRain)   
//  Snow 
    var mySnowItemList = gSnow.members.filter[ i| Integer.parseInt(i.name.split("_").get(1)) > daymin && Integer.parseInt(i.name.split("_").get(1)) <= daymax ]
    var Number sumSnow = 0
    mySnowItemList.forEach[ g|sumSnow = sumSnow + (((g.state as Number ).floatValue)*3) ]
    ScriptServiceUtil.getItemRegistry.getItem("localDaySnowTotal_"+counter).postUpdate(sumSnow)   
//  Humidity
//
//  ++++++++++++++++++++++++++++++++++++++++  Concatenate for sitemap presentation ++++++++++++++++++++++++++++++++++++++++++++++++++++
    ScriptServiceUtil.getItemRegistry.getItem("localDayTempForecast_"+counter).postUpdate( new DateTime().plusDays(counter).toString("EE, dd.MMM") + ": min/max/avg: "  + " / " + 
       ScriptServiceUtil.getItemRegistry.getItem("localDayTempMin_"+counter).state.format("%.1f").toString  + " / " +
       ScriptServiceUtil.getItemRegistry.getItem("localDayTempMax_"+counter).state.format("%.1f").toString  + " / " +
       ScriptServiceUtil.getItemRegistry.getItem("localDayTempAVG_"+counter).state.format("%.1f").toString )

    counter++
  }  // End While
  logInfo("forecasting","Roger, over and out")
end
Das Ergebnis sieht dann so in der BasicUI aus.
temp.jpg
Die Items-Datei ist im Anhang beigefügt, falls einer Interesse hat.

@udo1toni, nochmals vielen Dank für deine Tipps und Anregungen. Ohne dich hätte ich das nie hingekriegt. Dadurch habe ich wieder einiges dazulernen können. Vielleicht siehst du ja noch das eine oder andere was man verbessern könnte.

Gibt es irgendwo etwas zum Nachlesen über die Funktionen/Methoden für diese ".members"?

Was für Feldtypen sind diese "myTempItemList.", etc. eigentlich ?

Grüsse aus dem Schwabenland
Peter
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von udo1toni »

peter-pan hat geschrieben: 11. Sep 2019 15:32 Was für Feldtypen sind diese "myTempItemList.", etc. eigentlich ?
Gar keins :D

Na ja, es handelt sich in dem Fall ja um eine Aufzählung bzw. eine Liste von Items. Da könnten durchaus auch unterschiedliche Typen dahinter stecken, aber darauf achtet man ja sowieso (hüstel...)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von peter-pan »

Hmmm ?! Hab mich wohl etwas falsch aus gedrückt. Ich meinte eigentlich nicht den Inhalt, sondern das Ergebnis

Code: Alles auswählen

var myHumItemList = gHum.members.filter[ i| Integer.parseInt(i.name.split("_").get(1)) > daymin && Integer.parseInt(i.name.split("_").get(1)) <= daymax ]
das links vom "Gleichheitszeichen" steht (var myHumItemList). Ist das eine ArrayList oder eine Map oder was ganz anderes ? :cry: :oops:
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von udo1toni »

Ich meinte auch das Ergebnis :) myHumItemList ist eine Liste.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

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

Re: Optimierung OWM-Rule - Berechnung Tagesgesamtwerte

Beitrag von peter-pan »

Danke. Habe die Regel jetzt noch um "Luftfeuchtigkeit" und "Luftdruck" erweitert. Ging ganz schnell und einfach.
Bin nach wie vor total begeistert von deinem "Geistesblitz".
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Antworten