Hi all,
I’ve been having difficulty accessing persistence data. My default persistence is mapdb (largely to be able to restore all the data/switches/etc without a huge data footprint), but most of my data I care about goes to influxdb (not sure if this default setting is where the problem is). I can come up with all sorts of beautiful graphs with this data - most of it for the past year - so the persistence is working well from that end.
I’ve been writing rules to trigger bathroom fans based on humidity, and seem to run into an error using
Ensuite_Humidity.averageSince(now.minusHours(4))
I am persisting all humidity items every 1hour and every change. I don’t believe I have any null values involved, as all the sensors have been working well recently. When a rule calls the averageSince function, I get an error in the logs.
My relevant rule:
rule "Ensuite Bathroom Humidity"
when
Item Ensuite_Humidity changed
then
var Number calcDownstairsAverage=0
logInfo("BathroomFans.rules", "About to call up historical value.")
var Number prevAverage = Ensuite_Humidity.averageSince(now.minusHours(4))
var Number TriggerHumidity1=DownstairsAverageHumidity.state +11
var Number TriggerHumidity2=prevAverage+11
var Number StopHumidity1=DownstairsAverageHumidity.state+9
var Number StopHumidity2=prevAverage+9
var Number MinHumidity = 47
logInfo("BathroomFans.rules", "About to calculate average.")
calcDownstairsAverage = (Ensuite_Humidity.state+Livingroom_Humidity.state+Mudroom_Humidity.state+GuestBath_Humidity.state+hallwayHumidity.state)/5
logInfo("BathroomFans.rules", "Average calculated.")
logInfo("BathroomFans.rules", calcDownstairsAverage)
logInfo("BathroomFans.rules", "About to update item.")
DownstairsAverageHumidity.sendCommand(calcDownstairsAverage)
logInfo("BathroomFans.rules", "Updated item.")
logInfo("BathroomFans.rules", DownstairsAverageHumidity.state)
if((Ensuite_Humidity.state >= TriggerHumidity1)||(Ensuite_Humidity>=TriggerHumidity2)){
logInfo("BathroomFans.rules", "Ensuite Humidity Rule Triggered.")
val StringBuilder message = new StringBuilder("Ensuite Bathroom Humidity is ")
message.append(Ensuite_Humidity.state)
message.append(". ")
if (Ensuite_Humidity.state >= MinHumidity) {
if(Ensuite_Humidity.state >= TriggerHumidity1) {
message.append("This is higher than regional humidity threshold )")
message.append(TriggerHumidity1)
message.append("). ")
}
if(Ensuite_Humidity.state >= TriggerHumidity2) {
message.append("This is higher than previous average humidity threshold (")
message.append(TriggerHumidity2)
message.append("). ")
}
if (FF_EnsuiteShowerFan.state == OFF) {
FF_EnsuiteShowerFan.sendCommand(ON)
FF_EnsuiteToiletFan.sendCommand(ON)
message.append("Turning on shower and toilet fans.")
}
else {
message.append("Fan already on.")
FF_EnsuiteToiletFan.sendCommand(ON) // ensuring the toilet fan is on, and not needlessly complicating the code
}
}
else {
message.append("This still below the minimum humidity threshold (")
message.append(MinHumidity)
message.append(")")
}
logInfo("BathroomFans.rules", message)
}
else if ((((Ensuite_Humidity.state < StopHumidity1)&&(FF_EnsuiteShowerFan.state == ON))||((Ensuite_Humidity.state < StopHumidity2)&&(FF_EnsuiteShowerFan.state == ON)))&&(StillShowering==OFF)) {
val StringBuilder message = new StringBuilder("Ensuite Bathroom Humidity is ")
message.append(Ensuite_Humidity.state)
message.append(". ")
if (Ensuite_Humidity.state < StopHumidity1) {
message.append("This is now lower than the regional humidity threshold (")
message.append(StopHumidity1)
message.append(") Turning off shower fan.")
}
if (Ensuite_Humidity.state < StopHumidity2) {
message.append("This is now lower than the previous average humidity threshold (")
message.append(StopHumidity2)
message.append(") Turning off shower fan.")
}
logInfo("BathroomFans.rules", message)
FF_EnsuiteShowerFan.sendCommand(OFF)
FF_EnsuiteToiletFan.sendCommand(OFF)
}
end
and my relevant log:
2019-11-06 11:52:37.397 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'BathroomFans.rules'
2019-11-06 11:52:44.282 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'BathroomFans.rules'
2019-11-06 11:52:57.449 [INFO ] [home.model.script.BathroomFans.rules] - About to call up historical value.
2019-11-06 11:52:57.459 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Ensuite Bathroom Humidity': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_plus(java.lang.Object,java.lang.String) on instance: null
and my persistence:
// influxdb persist file
Strategies {
everyMinute : "0 * * * * ?"
everyHour : "0 0 * * * ?"
everyDay : "0 0 0 * * ?"
every2Minutes : "0 */2 * ? * *"
every5Minutes : "0 */5 * ? * *"
every15Minutes : "0 */15 * ? * *"
default = everyChange
}
Items {
gTemperatureItems*: strategy = everyHour, everyChange
gHumidityItems*: strategy = everyHour, everyChange
gMotionItems*: strategy = every15Minutes, everyChange
gAnyRecentMotion*: strategy = every15Minutes, everyChange
gLightSensorItems*: strategy = everyHour, everyChange
gWeatherTemp*, gWeatherHumidity*: strategy = everyHour
Presence_Sensors*: strategy = every15Minutes, everyChange
gLock*: strategy = every15Minutes, everyChange
gFans*: strategy = everyChange, everyDay
gEspMotion*: strategy = everyChange
}
A snippet of my graphana data for today. (FYI, the downards spike in humidity on the ensuite fan was me toggling the data between values to artifically trigger my rule)
Any ideas on directions to go from here?
If I have default persistence being mapdb, does this affect the averageSince function? Is there anyway to specify which persistence I have averageSince use, rather than having to switch everything to influxdb?
Thanks
Ben
OH 2.4 on Raspberry Pi3B (Openhabian) with zwave snapshot 2.5 as of Nov 5th.