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.
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
aufgeht.