Logging timer "state"

I´m currently testing with timers and I want to know the timer “state” (what´s the current count) if a rule will execute something. So that´s my question: How could I log the timer “state”?

I´ve created a timer with

timers.put(sw.name, createTimer(now.plusSeconds(TimerTimeoutSeconds), [| … ]))

But if I want to log the timer with

logInfo(“testrule”, "Time remaining: " + (timers.get(sw.name)))

i´ll get

“Time remaining: org.eclipse.smarthome.model.script.internal.actions.TimerImpl@224ecf”

I’m not able to test this right now so I can’t say for sure, but I don’t think there is a way to get the time remaining in a timer. You can see if the timer has expired or is active but there’s is no “count down” with a timer. A Timer gets scheduled for a certain absolute time.

You could possibly get the time the timer is scheduled for and then do some math to see how much timer is left. I don’t know for sure.

You should use VSCode with the openHAB extension. Then you can type “timer.” And it will list all the methods available on timer.

If there is no way to get the time the timer is scheduled for, you can save a datestamp and use that to calculate the amount if time left on the timer.

Thanks @rlkoshak - thats not the answer I hope to get but it cleared my fails. I tried with VSC but I didn´t get the syntax check working (but thats an other issue).

Do you know how I could get an output from the complete hashmap which I declared with val Map<String, Timer> timers = newHashMap? Maybe I´ll get from this result the answer I have to know.

If what you are trying to figure out is how much time is left on a timer, there is nothing from a Map that will tell you anything relevant.

What are you trying to do?

I´m still trying to configure two hue motion sensors with different light settings depending on time and with dimming function. I found out that hue motion sensor won´t go OFF if a constant motion detects. The most time my setup is working but in morning hours if my family is preparing for going out of house and the motion sensors are alternate detecting motion my setup still not working perfectly - normally the timer should be canceled if motion will detect but in a rare case it isn´t working. So it would be nice if I could log the timer to find out what the problem is. BTW: It doesn´t help that logInfo will goes to openhab.log and all events goes to events.log so I don´t get a complete logfile. Are there other options to get a better overview?

You can change the logging config so everything goes to the same file.

Post your complete rule and Items definitions.

I will read :slight_smile:

.items

Group:Switch:OR(ON, OFF)        gLightHallwaySwitch
Group:Dimmer:AVG                gLightHallwayDimmer
Switch DimmStufe
Group:Switch:OR(ON, OFF) gMotion "Bewegungsmelder" <motion> (Home)

Switch  Light1_Toggle "Licht Spot1" <light> (Hallway,gLight,gLightHallwaySwitch) { channel="hue:0220:0017884804a5:bulb1:brightness" }
Dimmer  Light1_Dimm   "Licht Spot1" <light> (Hallway,gLight,gLightHallwayDimmer) { channel="hue:0220:0017884804a5:bulb1:brightness" }
[...]
Switch  Light4_Toggle "Licht Spot4" <light> (Hallway,gLight,gLightHallwaySwitch) { channel="hue:0220:0017884804a5:bulb4:brightness" }
Dimmer  Light4_Dimm   "Licht Spot4" <light> (Hallway,gLight,gLightHallwayDimmer) { channel="hue:0220:0017884804a5:bulb4:brightness" }

Switch hueMotionSensor_1_Presence "presence [%s]" <motion> (Hallway,gMotion) { http="<[hueMotionSensor_1_Presence:100:JS(getHuePresence.js)]" }
Switch hueMotionSensor_2_Presence "presence [%s]" <motion> (Hallway,gMotion) { http="<[hueMotionSensor_2_Presence:100:JS(getHuePresence.js)]" }

.rules

import java.util.Map
val Map<String, Timer> timers = newHashMap
val Map<String, Timer> dimmers = newHashMap

rule "Rule 2: Bewegungsmelder Flur - Lichtsteuerung"
when
    Item gMotion changed from OFF to ON
then
    logInfo("rule_2", "Start")

    // Variablen
    var hour   = now.getHourOfDay
    val TimerTimeoutSeconds = 90

    // Regel
    if (AfriColaButton.state == OFF) {
        if ( timers.get(gLightHallwaySwitch) !== null) {
            logInfo("rule_2", "Dimm-Stufe noch nicht erreicht. Timer wird zurueckgesetzt ...")
            timers.get(gLightHallwaySwitch).reschedule(now.plusSeconds(TimerTimeoutSeconds))
        }
        if ( dimmers.get(gLightHallwaySwitch) !== null) {
            logInfo("rule_2", "Timer ist schon auf Null, aber Dimm-Timer noch nicht erreicht.")
            dimmers.get(gLightHallwaySwitch).cancel
            dimmers.put(gLightHallwaySwitch, null)
        }
        if ((timers.get(gLightHallwaySwitch) === null) && (dimmers.get(gLightHallwaySwitch) === null)) {
            if ( hour < 7 || hour >= 22 ) {
                // Nachtschaltung
                logInfo("rule_2", "Nachtschaltung")
                sendCommand(gLightHallwayDimmer, 10) }
            if ( hour < 22 && hour >= 20 ) {
                // Abendschaltung
                logInfo("rule_2", "Abendschaltung")
                sendCommand(gLightHallwayDimmer, 30) }
            if ( hour < 20 && hour >= 7 ) {
                // Tagschaltung
                logInfo("rule_2", "Tagesschaltung")
                sendCommand(gLightHallwayDimmer, 100) }
        }
    }
    logInfo("rule_2", "Ende")
end

rule "Rule 3: Bewegungsmelder Flur - Zeitsteuerung"
when
    Item gMotion changed from ON to OFF
then
    logInfo("rule_3", "Start")

    // Variablen
    Thread::sleep(100) // give persistence time to save the update
    val TimerTimeoutSeconds = 90
    val DimmerTimeoutSeconds = 30

    // Regel
    if (AfriColaButton.state == OFF) {
        if ((timers.get(gLightHallwaySwitch) === null) && (dimmers.get(gLightHallwaySwitch) === null)) {
            logInfo("rule_3", "Timer wird gestartet.")
            timers.put(gLightHallwaySwitch, createTimer(now.plusSeconds(TimerTimeoutSeconds), [|
                logInfo("rule_3", "Timer abgelaufen, jetzt wird gedimmt.")
                sendCommand(gLightHallwayDimmer, 10)
                logInfo("rule_3", "Dimmer wird gestartet.")
                dimmers.put(gLightHallwaySwitch, createTimer(now.plusSeconds(DimmerTimeoutSeconds), [|
                    logInfo("rule_3", "Dimmer timer abgelaufen, jetzt wird ausgeschalten")
                    sendCommand(gLightHallwaySwitch, OFF)
                    logInfo("rule_3", "Variable dimmers wird zurückgesetzt.")
                    dimmers.put(gLightHallwaySwitch, null)
                ]))
                logInfo("rule_3", "Variable timers wird zurückgesetzt.")
                timers.put(gLightHallwaySwitch, null)
            ]))
        }
    }
    logInfo("rule_3", "Ende")
end

Use the name of your Items/Groups for the key in your maps. For example:

if( timers.get(gLightHallwaySwitch.name) !== null) {

Why do you have separate timers for the same lights as a Switch verses Dimmer? Are you aware you can treat a Dimmer as if it were a Switch (i.e. send it ON/OFF commands, put it on your sitemap as a Switch, etc)?

I don’t think your gMotion Group will work like you think it does. Consider this scenario:

  1. All motion sensors are OFF, gMotion is OFF
  2. Motion sensor 1 goes to ON, gMotion goes to ON, Rule 2 fires
  3. Motion sensor 2 goes to ON, nothing happens because gMotion is already ON
  4. Motion sensor 1 goes to OFF, nothing happens because sensor 2 is still ON so gMotion remains ON
  5. Motion sensor 2 goes to OFF, gMotion goes to OFF, Rule 3 fires

I suspect your problem is the trigger to your Rule. Change the Group to Group:Number:SUM gMotion and now gMotion will change whenever any of the motion sensors changes state. But you will have to merge your two Rules.

Alternatively trigger your Rule with the motion sensors themselves:

when
    Item hueMotionSensor_1_Presence changed from OFF to ON or
    Item hueMotionSensor_2_Presence changed from OFF to ON
then

Thanks, I have changed.

I set up different timers because I need different timers :slight_smile:. I want that a sensor will detect motion and if no motion will detect a timer should start for 90 seconds. After 90 seconds the light should dimmed to 10% for 30 seconds. After ending the second timer the light should go off.

Well I think thats the behavior I want to have. Only if both motion sensors are OFF (means no presence detected) the timer should start. If the timers is running and motion will detect the timer should reschedule (and I think there is the problem: the timer should canceled) and if the timers is off but the dimmers are running the dimmers should canceled and the light should go on previous state.

I will change the rule2 to cancel the timer if the timers is running and hope that tomorrow morning the rules will work like expected :wink:

But that is the problem. The timer won’t get resecheduled for new motion detection events because gMotion is already ON.

You have to change the rule to trigger everytime any of the motion sensors goes to ON. By using the gMotion group to trigger the rule, the timer gets created and then never gets rescheduled because gMotion never changes until everything goes back to OFF.

You´re totally right! I reconfigure rule2 and I will see more tomorrow. Thanks!