I try to realize a counter which displays the minutes and the seconds in the sitemap.
The counter runs but it displays the minutes with always 30 and the seconds with always 0.
I used a “while” cycle within a “while” cycle. Probably the mistake is within this. But I can’t find the failure.
Has anyone an idea whats going wrong?
rule "Heizung_Bad_ausschalten"
when
Item heizung_1 received command ON
then
var Number z
var Number x
var i = -1
var l = 0
schleife_heizung_min.postUpdate(30)
while ((i=i+1) < 31) { // 30 Minuten
while ((l=l+1) < 61) {
Thread::sleep(6000) // 1 Minute: 1 x 60 x 1000
if (heizung_1.state == OFF) {
i = 30
l = 60
x=60-l
schleife_heizung_sec.postUpdate(x)
}
}
z=30-i
schleife_heizung_min.postUpdate(z)
}
sendCommand(heizung_1, OFF)
end
First: Thread::sleep(6000) is 6 seconds. This may be a Typo in your rule.
Second: the if-clause is to reset the timer, right? You should set the curly bracket at the right place, so
if (heizung_1.state == OFF) {
i = 30
l = 60
}
x=60-l
schleife_heizung_sec.postUpdate(x)
but there is another problem, that has nothing to do with the rule itself. The UI won’t update every second
So, simplest way would be to countdown only minutes, and don’t do it with a Thread::sleep, you would start the thread itself for 30 Minutes, better use timers:
var Timer myTimer = null
var int myMinutes = 30
rule "switch off bath heating"
when
Item heizung_1 received command
then
if (receivedCommand == ON) {
if (myTimer==null || myTimer.hasTerminated)
myTimer = createTimer(now.plusMinutes(1), [|
myMinutes = myMinutes - 1
if (myMinutes > 0) {
myTimer.reschedule(now.plusMinutes(1))
schleife_heizung_min.postUpdate(myMinutes)
}
else
heizung_1.sendCommand(OFF)
]
)
}
else
myTimer.cancel
myTimer = null
myMinutes = 30
schleife_heizung_min.postUpdate(0)
end
This will create a timer, which will fire after 60 seconds. The timer will restart itself and count down to zero.
thank you for this rather great support.
I tried to avoid a timer as I had in the past exact with this rule some problems with the timer. But you are right, a time is much better and I will use your code.
Only for information. Here my complete code. It shows each minute and second in the UI. Sometimes a second is missing, but it runs.
rule "Heizung_Bad_ausschalten"
when
Item heizung_1 received command ON
then
var Number z
var Number x
var i = 0
schleife_heizung_min.postUpdate(30)
while ((i=i+1) < 31) { // 30 Minuten
var l = 0
while ((l=l+1) < 61) {
Thread::sleep(100) // 1 Minute
if (heizung_1.state == OFF) {
i = 30
l = 60
}
x=60-l
schleife_heizung_sec.postUpdate(x)
}
z=30-i
schleife_heizung_min.postUpdate(z)
}
sendCommand(heizung_1, OFF)
end