I have a set of timers, depending on my wake-up time (alarm of alexa), the thermostats are controlled. Bad is never getting the call to switch to daytime-cold - so I don’t see the log entry “Timer Bad fertig”. Rule:
rule "wakeup"
when
Item Echo_Next_Alarm changed
then
wakeupTimer?.cancel
HeatTimer_Bad_SetWarm?.cancel
HeatTimer_Bad_SetCold?.cancel
HeatTimer_Arbeitszimmer_SetWarm?.cancel
HeatTimer_Arbeitszimmer_SetCold?.cancel
if (Echo_Next_Alarm.state == UNDEF) {
logInfo("wakeup", "Timer cancelled")
} else {
logInfo("wakeup", Echo_Next_Alarm.state.format("%1$td.%1$tm.%1$ty %1$tH:%1$tM"))
wakeupTimer = createTimer(new DateTime((Echo_Next_Alarm.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli))[|
logInfo("wakeup", "Time is up")
wakeupTimer = null
]
HeatTimer_Bad_SetWarm = createTimer(new DateTime((Echo_Next_Alarm.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).minusHours(2))[|
logInfo("wakeup", "Timer Bad aufheizen")
Solltemperatur_Bad.sendCommand(22)
HeatTimer_Bad_SetWarm = null
]
HeatTimer_Bad_SetCold = createTimer(new DateTime((Echo_Next_Alarm.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusHours(1))[|
logInfo("wakeup", "Timer Bad fertig")
Solltemperatur_Bad.sendCommand(19)
HeatTimer_Bad_SetCold = null
]
HeatTimer_Arbeitszimmer_SetWarm = createTimer(new DateTime((Echo_Next_Alarm.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).minusHours(3))[|
logInfo("wakeup", "Timer Arbeitszimmer aufheizen")
Solltemperatur_Arbeitszimmer.sendCommand(22)
HeatTimer_Arbeitszimmer_SetWarm = null
]
HeatTimer_Arbeitszimmer_SetCold = createTimer(new DateTime((Echo_Next_Alarm.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusHours(1))[|
logInfo("wakeup", "Timer Arbeitszimmer fertig")
Solltemperatur_Arbeitszimmer.sendCommand(19)
HeatTimer_Arbeitszimmer_SetCold = null
]
}
end
Logfile:
2019-12-09 22:04:11.728 [INFO ] [clipse.smarthome.model.script.wakeup] - 10.12.19 05:50
2019-12-10 02:50:00.006 [INFO ] [clipse.smarthome.model.script.wakeup] - Timer Arbeitszimmer aufheizen
2019-12-10 03:50:00.005 [INFO ] [clipse.smarthome.model.script.wakeup] - Timer Bad aufheizen
2019-12-10 05:50:00.005 [INFO ] [clipse.smarthome.model.script.wakeup] - Time is up
2019-12-10 05:50:20.600 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'wakeup': 'cancel' is not a member of 'java.lang.Object'; line 25, column 2, length 39
2019-12-10 06:50:00.005 [INFO ] [clipse.smarthome.model.script.wakeup] - Timer Arbeitszimmer fertig
var Timer wakeupTimer = null
var Timer HeatTimer_Bad_SetWarm = null
var Timer HeatTimer_Bad_SetCold = null
var HeatTimer_Arbeitszimmer_SetWarm = null
var HeatTimer_Arbeitszimmer_SetCold = null
Feels like you have another rule interfering with wakeupTimer.
You declared it as a Timer object. It will get set to null, and later by createTimer, and later still null again.
So wakeupTimer?.cancel
should operate on either a Timer object or be omitted by the ? if null Rule 'wakeup': 'cancel' is not a member of 'java.lang.Object'
seems to imply that it is neither at that moment.
Are you expecting this rule to be run again while some of its child timers are still active? It would have cancelled the Arbeitszimmer +1 timer had the rule not errored.
I have to explain the code a bit: In the evening I tell alexa what time I want to wake up, this triggers the “Echo_Next_Alarm” change. - Log entry at 22:04
First I clear any timer that is running. Then I create 5 timers.
The wakeupTimer is printing the “Time is up” log message exactly at the right time.
20 seconds after that I get the error message. Maybe alexa is executing an “Echo_Next_Alarm” change to “UNDEF”? Which I should catch, but the error should prevent that “HeatTimer_Bad_SetCold” is cancelled, as “HeatTimer_Arbeitszimmer_SetCold” is executing see below.
The Heater in “Arbeitszimmer” is turned on 3 hours ahead of time.
The Heater in “Bad” is turned on 2 hours ahead of time.
The Heater in “Arbeitszimmer” is turned off 1 hour after the wakeup call.
But - the heater in “Bad” does not turn off 1 hour after the wakeup call.
Because you cancelled it.
At 05:50:20, your Echo_Next_Alarm is changed.
Your HeatTimer_Bad_SetCold still has an hour to go yet
but
the change makes your rule run
and HeatTimer_Bad_SetCold?.cancel
cancels the Bad timer
I think that is the big clue. The error message about cancel is not coming from wakeupTimer?.cancel
but from one of HeatTimer_Arbeitszimmer_SetWarm?.cancel HeatTimer_Arbeitszimmer_SetCold?.cancel
You could prove that by adding progress logInfo()
Why, what is different about those? Udo has already spotted that -
You are going to need to rethink your strategy to deal with Alexa “announcing” alarm time has passed.
Now I see it, yes! I changed that, so tomorrow I should run into the situation where the two timers HeatTimer_Bad_SetCold and HeatTimer_Arbeitszimmer_SetCold are cancelled before they execute - so temperature will stay at 22 during the day.
var Timer wakeupTimer = null
var Timer HeatTimer_Bad_SetWarm = null
var Timer HeatTimer_Bad_SetCold = null
var Timer HeatTimer_Arbeitszimmer_SetWarm = null
var Timer HeatTimer_Arbeitszimmer_SetCold = null
Be interesting to see. So far as I can see, at the moment of failure the last thing that happened to that variable was assignment = to createTimer. I’d have thought that would force it into a Timer type object.
Result:
As expected: HeatTimer_Bad_SetCold and HeatTimer_Arbeitszimmer_SetCold are cancelled before they execute - so temperature will stay at 22 during the day.
Still I get the error:
2019-12-11 05:50:00.005 [INFO ] [clipse.smarthome.model.script.wakeup] - Time is up
2019-12-11 05:50:05.467 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'wakeup': 'cancel' is not a member of 'java.lang.Object'; line 25, column 2, length 39
There is no other code calling this timer. I also did expect the behaviour explained in post 2:
You declared it as a Timer object. It will get set to null , and later by createTimer, and later still null again.
So wakeupTimer?.cancel
should operate on either a Timer object or be omitted by the ? if null
I’m still suspicious something else is using one of those variable names. someVariable?.cancel
will break in with the error you get if it is neither null nor a Timer object.
It is a Heisenbug!
A Heisenbug is a bug that disappears when you try to observe it.
So this morning all the log mesages and no error message.
The logInfo propably forced a type check/type cast? I’m not familiar with the behaviour of such interpreters, having used strongly typed languages only.