Dim light depending on the time in timer

In the original Philips Hue Motion Sensor rules

  1. a light will be set on if Motion Sensor detect something.
  2. After then a timer will be started (I think 3 minutes).
  3. And 30 seconds before timer will be of a command will be dim the lights.
  4. if timer stop light will be set off
  5. if timer is running an motion will detect the timer is restarting

I have a rule, that covered point 1 and 2 (and 4 and 5) but I have no clue how to solve point 3.
Here is my current rule

rule "Rule 3"
when
    Item BewegungsmelderFlur_1 changed from OFF to ON
then
    logInfo("rule_3", "Start")
    Thread::sleep(100) // give persistence time to save the update

    var hour = now.getHourOfDay
    val int timeoutMinutes = 3

    if (timers3 === null){
        if ( hour < 7 || hour >= 22 ) {
            logInfo("rule_3", "Nachtschaltung")
            sendCommand(gLightTestDimmer, 10) }
        if ( hour < 22 && hour >= 20 ) {
            logInfo("rule_3", "Abendschaltung")
            sendCommand(gLightTestDimmer, 30) }
        if ( hour < 20 && hour >= 7 ) {
            logInfo("rule_3", "Tagesschaltung")
            sendCommand(gLightTestDimmer, 100) }
        timers3 = createTimer(now.plusMinutes(timeoutMinutes), [|
            sendCommand(gLightTestSwitch, OFF)
            timers3 = null ])
   }
    else {
        logInfo("rule_3", "Timer wird zurueckgesetzt ...")
        timers3.reschedule(now.plusMinutes(timeoutMinutes))
    }
end

The question is: How could I get time remaining from the Timer? And is it possible to add the dim function into this rule or should it an additional rule?

Hello

Why you dont split it into 2 timers?
Instead of Timeout 3 minutes - 30 seconds.
Timer 1 2min 30s, Timer 2 30s

Do you mean like that?

var Timer timer3 = null
var Timer dim3 = null

rule "Rule 3"
when
    Item BewegungsmelderFlur_1 changed from OFF to ON
then
    logInfo("rule_3", "Start")
    Thread::sleep(100) // give persistence time to save the update

    var hour = now.getHourOfDay
    val int timeoutMinutes = 3
    val int dimSeconds = 30

    if (timers3 === null){
       //Switch Light On
       sendCommand(gLightTestDimmer, 100) }
       //Start timer
       timers3 = createTimer(now.plusMinutes(timeoutMinutes), [|
            sendCommand(gLightTestDimmer, 30)
            dim3 = createTimer(now.PlusSeconds(dimSeconds), [|
            sendCommand(gLightTestSwitch, OFF)
            timers3 = null ])
            dim3 = null ])
   }
    else {
        logInfo("rule_3", "Timer wird zurueckgesetzt ...")
        dim3 = null
        timers3.reschedule(now.plusMinutes(timeoutMinutes))
    }
end

Maybe this could work - but isnĀ“t it to complicated to restart the timer? I donĀ“t know if it works if the dim3 Timer is started.

Hello Controlc

Yes, this should it be nearly.

if (timers3 === null){

should be

if ((timers3 === null) && (dim3 == null)){
timers3 = createTimer(now.plusMinutes(timeoutMinutes), [|
            sendCommand(gLightTestDimmer, 30)
            dim3 = createTimer(now.PlusSeconds(dimSeconds), [|
               sendCommand(gLightTestSwitch, OFF)
               dim3 = null ])           
            timers3 = null ])
            

and

else if ((timers3 != null) && (dim3 == null)) {
        logInfo("rule_3", "Timer wird zurueckgesetzt ...")
        dim3.cancel
        dim3 = null
        timers3.reschedule(now.plusMinutes(timeoutMinutes))
    }
else if (dim3 != null) {
   dim3.cancel
   dim3 = null
   timers3 = createTimer(now.plusMinutes(timeoutMinutes), [|
            sendCommand(gLightTestDimmer, 30)
            dim3 = createTimer(now.PlusSeconds(dimSeconds), [|
               sendCommand(gLightTestSwitch, OFF)
               dim3 = null ])           
            timers3 = null ])

This code is written out of the head, with no validation.
The idea is to check wich dimmer is running (because if dim3 is running, the light is already dimmed)

BTW with your setting you have now 3 min + 30 s.
If oyu change timer3 to 90 seconds you archive the 3 minutes goal.

regards
Michael

1 Like

Hi Michael,

IĀ“ve used your code (with some simple corrects) and now thats the complete rule:

var Timer timers3 = null
var Timer dim3 = null

rule "Rule 3"
when
    Item BewegungsmelderFlur_1 changed from OFF to ON
then
    logInfo("rule_3", "Start")
    Thread::sleep(100)

    var hour   = now.getHourOfDay

    val int timeoutSeconds = 90
    val int dim3Seconds = 30

    logInfo("rule_3", "Motion rule: Wir haben die Stunde " +hour)

    if ((timers3 === null) && (dim3 === null)){
        if ( hour < 7 || hour >= 22 ) {
            // Nachtschaltung
            logInfo("rule_3", "Nachtschaltung")
            sendCommand(gLightTestDimmer, 10) }
        if ( hour < 22 && hour >= 20 ) {
            // Abendschaltung
            logInfo("rule_3", "Abendschaltung")
            sendCommand(gLightTestDimmer, 30) }
        if ( hour < 20 && hour >= 7 ) {
            // Tagschaltung
            logInfo("rule_3", "Tagesschaltung")
            sendCommand(gLightTestDimmer, 100) }

        timers3 = createTimer(now.plusSeconds(timeoutSeconds), [|
            sendCommand(gLightTestDimmer, 10)
            dim3 = createTimer(now.plusSeconds(dim3Seconds), [|
                sendCommand(gLightTestSwitch, OFF)
                dim3 = null ])
            timers3 = null ])
        }

   else if ((timers3 !== null) && (dim3 === null)) {
        logInfo("rule_3", "Dimm-Stufe noch nicht erreicht. Timer wird zurueckgesetzt ...")
        timers3.reschedule(now.plusSeconds(timeoutSeconds))
        }

   else if (dim3 !== null) {
        logInfo("rule_3", "Timer bereits in Dimm-Stufe. Timer wird zurueckgesetzt ...")
        dim3.cancel
        (dim3 = null)

        if ( hour < 7 || hour >= 22 ) {
            // Nachtschaltung
            logInfo("rule_3", "Nachtschaltung")
            sendCommand(gLightTestDimmer, 10) }
        if ( hour < 22 && hour >= 20 ) {
            // Abendschaltung
            logInfo("rule_3", "Abendschaltung")
            sendCommand(gLightTestDimmer, 30) }
        if ( hour < 20 && hour >= 7 ) {
            // Tagschaltung
            logInfo("rule_3", "Tagesschaltung")
            sendCommand(gLightTestDimmer, 100) }

        timers3 = createTimer(now.plusSeconds(timeoutSeconds), [|
            sendCommand(gLightTestDimmer, 30)
            dim3 = createTimer(now.PlusSeconds(dim3Seconds), [|
                sendCommand(gLightTestSwitch, OFF)
                dim3 = null ])
            timers3 = null ])
        }
    logInfo("rule_3", "End")
end

So itĀ“s working but I have to say ā€œSchƶn ist was anderes!ā€ - My hope was a more shorter code but hey: It works! :slight_smile:

Thanks a lot! But if someone else got a better solution IĀ“m already interested :smiley:.

You are so right ^^ But the code is, was nobody seeā€™s. Only the result.
I would be happy to learn a easier way.

BR
Michael