Rule Machine | toilet licht trigger sunset en action motion

Good afternoon,

Can someone please explain to me what I’m probably doing wrong?
I created a rule in Rule Machine with the following:
Trigger: Sunset
Action: When the Hue sensor becomes active, turn on the toilet lamp.
Wait for event: When the Hue sensor becomes inactive and stays inactive for 2 minutes.
Off: Turn off the Hue lamp.

Unfortunately, nothing happens. I can see that the sensor becomes active in Rule Machine when I walk past it, but the lamp doesn’t turn on.

Hubitat is C8 PRO

kind regard, Andre

Your rule as written triggers at sunrise. That means your actions will run. So, at sunrise, if motion happens to be active, the light will turn on.

You didn't say what you actually want to happen (in normal language, not in Rule Machine terms -- this is a good demonstration of why that can be helpful), but I suspect this is not it. You probably want motion to be a trigger and maybe use something related to time as a condition (though likely something between two times and not one specific time).

The Rule 5.1 docs may also be good to read, or you could consider using a simpler app like Basic Rule to start.

2 Likes

Hi Bert,

In Basic Rules, you can’t create a trigger that starts with sunrise and then immediately use a motion sensor as the first action.
In other words, you can’t say ā€œat sunrise (so everything after sunrise), then when the Hue motion sensor is active, etc.ā€
(But that’s okay for now — I’d still like to experiment a bit with Rule Machine, although I do sometimes struggle with the logic.)

But regarding Rule Machine
sorry, I don’t quite understand you, because what I’m saying is:
*** At sunrise** (so starting from sunrise, which I assume means the whole day until sunset)
do: when the Hue motion sensor is active, etc.

Aren’t I already telling it what to do then?

kind regard, Andre

1 Like

In hopes this may be helpful, remember that Triggers are always events and Conditions are always states.

For example, Time = Sunrise is an event, but Time = between Sunrise and Sunset is a state. Switch turning On = event, but Switch is On = state. Etc.

1 Like

That's not what "Trigger" means in Rule Machine, though. Please read the docs I linked to above, or at least the section that explains what triggers and actions are. A trigger is an event (not a state). When a trigger happens, the actions run. You rule will trigger (i.e., its actions will run) exactly once per day, at sunrise. Again, this is probably not what you want.

Actions are also executed at the time when they are reached. If motion is not active at exactly sunrise, that action will be skipped -- and never run again until the rule is triggered again. (The rest of the actions will run but probably not do much most of the time.)

What you really want to create this automation is motion as a trigger. Then you can check the time as a condition in your actions. You can't just say "sunrise" here -- both because the UI literally won't let you but also because the hub can't possibly know what you mean if you don't give it two specific times where you want the condition to be true. For example, you could say "Time of day is between sunset and sunrise" or whatever you actually want.

In summary, something like this is probably what you want:

Trigger event: Motion active

Actions to run:
IF (Time of day is between sunrise and sunset) THEN
On: Light
END-IF
Wait for condition: motion inactive and stays that way for 0:02:00
Off: Light

There are again some nuances here, like whether you always want the light to turn off when motion becomes inactive or only during the specific times, as well. (Right now, it will do it any time.)

Hopefully you can see now that, even in Basic Rules, this is not what you want. You want to start with motion. In Basic Rules, you'd add time under "Restrictions" rather than somewhere in your actions, as it does not support conditional actions in the more powerful way RM does but can accomplish a similar goal for many automations with this feature instead.

3 Likes

hi Hydro you mean like this:

hi Bert,

like this? Hydro his tekst set me to this .. action.

Unfortunatelty, that won't work -- I respectfully urge you to take time to read the information and resources @bertabcd1234 has provided in order to better understand the basics of triggers, conditonal actions, etc

2 Likes

No, I gave you a specific example in my post above.

All the rules you have posted so far demonstrate a substantial misunderstanding of how Rule Machine trigger events work, if not the actions also. Rule Machine is very powerful but can also be complex and hard to learn. You will need to read the docs, look at examples, or experiment (and enable logging, which can be helpful) to learn. The above should still get you started -- I'm not sure why your rule ended up so different from that -- but I would highly recommend doing all of these to learn more if you write additional rules.

I assure you Basic Rule could also work for this automation. You will need to write it in a similar way, starting with the motion sensor. You can "import" it into Rule Machine later if you decide you need the extra power. In the meantime, Basic Rule (or other apps) may be helpful for grasping the concepts of how automations work in an event-driven platform like Hubitat. Good luck!

1 Like

tnx

You may also want to look at the Motion and Mode Lighting App. which is another way that you could do this. But as @bertabcd1234 and @hydro311 stated above, read the docs on rules. Very good to have a basic understanding to expand on later.

Just rewrite it to:

Trigger = motion = active
Action = If time = after sunset and before sunrise, turn on lamp
and then proceed with the rest of your rule

Yes, many of us have suggested this above already, yet the rules demonstrated after that point persist with the original problem. At this point, we will need to wait to hear back from the OP if they are able to create a rule as has been suggested (or find an alternate method to perform their automation).

2 Likes

Hi All,

got it (almost) working with (see printscreen)

The only trigger here is the sensor in the toilet.
TRIGGER: Hue sensor detects motion.

After about 20 seconds, it moves on to the actions. That makes sense because the Hue sensor takes around 20 seconds to switch from active back to idle.
Once it does, the actions run perfectly. The problem is, of course, that those 20 seconds aren’t acceptable.

The thing is, I don’t actually need a trigger like this — in principle, this trigger could stay active 24/7. I’ve tried several different options and gone through the document that many people have recommended.

Unfortunately, I just don’t see the solution. In short: I’m close, but not quite there yet. And I understand that for some people, these kinds of questions might be a bit annoying, but everyone has to start somewhere?

And yes, people will ask questions, and the document that keeps getting mentioned probably isn’t clear to everyone. It certainly hasn’t been for me, especially since English isn’t my native language.

kind regards, Andre

1 Like

You don't need the first WAIT. The trigger is the motion sensor becoming active. The IF is there to only let it run between those times. Be sure to add the end-if at the very end.

If you mean you always want to the light to turn, no matter what time of day/night than just remove the if statement. Anytime there is motion it will turn on.

3 Likes

That is good advice, For people not used to working with logic rules, just writing out what you want to do in plain english can help to decide how to approach writing the rule.

In this case, it is:

"A rule that will turn on the toilet lamp when the motion sensor is triggered, if the time is after sunset and before sunrise. Then when the sensor goes inactive, wait two minutes and then turn off the toilet lamp."

I put this into Deep Seek:

"Create a Hubitat app that allows the user to select a toilet lamp that will turn on the lamp when a motion sensor is triggered, if the time is after sunset and before sunrise. When the sensor goes inactive, wait two minutes and then turn off the toilet lamp."

I didn't test the app, but the code looks good. OP may want to try using AI to write their automations into apps they can copy into Apps code and install, assuming the prompt for what they want to do is correct,

Features

  1. Device Selection:
  • Choose a motion sensor to monitor
  • Choose a lamp to control
  1. Time-Based Control:
  • Only activates during nighttime (after sunset and before sunrise)
  • Includes configurable sunrise/sunset offsets
  1. Motion Handling:
  • Turns lamp on immediately when motion is detected (if nighttime)
  • Waits specified delay (default 2 minutes) after motion stops before turning off
  • Cancels pending turn-off if new motion is detected
  1. Day/Night Transitions:
  • Automatically adjusts when sunrise/sunset occurs
  • Turns lamp off if daytime begins while motion is active
  • Turns lamp on if nighttime begins while motion is active
  1. Debugging:
  • Optional debug logging
> definition(
>     name: "Toilet Lamp Control",
>     namespace: "yourNamespace",
>     author: "Your Name",
>     description: "Controls a toilet lamp based on motion, only during nighttime hours",
>     category: "Convenience",
>     iconUrl: "",
>     iconX2Url: "",
>     iconX3Url: ""
> )
> 
> preferences {
>     page(name: "mainPage")
> }
> 
> def mainPage() {
>     dynamicPage(name: "mainPage", title: "Toilet Lamp Control", install: true, uninstall: true) {
>         section("Devices") {
>             input "motionSensor", "capability.motionSensor", title: "Select Motion Sensor", required: true
>             input "toiletLamp", "capability.switch", title: "Select Toilet Lamp", required: true
>         }
>         section("Settings") {
>             input "turnOffDelay", "number", title: "Turn off delay (minutes)", defaultValue: 2, required: true
>             input "sunriseOffset", "number", title: "Sunrise offset (minutes)", defaultValue: 0, required: true
>             input "sunsetOffset", "number", title: "Sunset offset (minutes)", defaultValue: 0, required: true
>         }
>         section("Options") {
>             input "enableDebug", "bool", title: "Enable debug logging", defaultValue: false
>         }
>     }
> }
> 
> def installed() {
>     logDebug("Installed with settings: ${settings}")
>     initialize()
> }
> 
> def updated() {
>     logDebug("Updated with settings: ${settings}")
>     unsubscribe()
>     initialize()
> }
> 
> def initialize() {
>     subscribe(motionSensor, "motion", motionHandler)
>     subscribe(location, "sunriseTime", sunriseSunsetHandler)
>     subscribe(location, "sunsetTime", sunriseSunsetHandler)
>     state.lastMotionActive = false
>     state.nighttime = isNighttime()
>     logDebug("Initialized - Nighttime: ${state.nighttime}")
> }
> 
> def motionHandler(evt) {
>     logDebug("Motion event: ${evt.value}")
>     
>     if (evt.value == "active") {
>         // Motion detected
>         state.lastMotionActive = true
>         if (state.nighttime) {
>             logDebug("Turning on toilet lamp (nighttime)")
>             toiletLamp.on()
>         } else {
>             logDebug("Not turning on lamp - it's daytime")
>         }
>         unschedule("turnOffLamp") // Cancel any pending turn-off
>     } else {
>         // Motion inactive
>         state.lastMotionActive = false
>         if (toiletLamp.currentSwitch == "on") {
>             def delayMinutes = turnOffDelay ?: 2
>             logDebug("Scheduling lamp turn off in ${delayMinutes} minutes")
>             runIn(delayMinutes * 60, "turnOffLamp")
>         }
>     }
> }
> 
> def turnOffLamp() {
>     if (!state.lastMotionActive && toiletLamp.currentSwitch == "on") {
>         logDebug("Turning off toilet lamp after delay")
>         toiletLamp.off()
>     } else {
>         logDebug("Not turning off lamp - motion is active or lamp is already off")
>     }
> }
> 
> def sunriseSunsetHandler(evt) {
>     logDebug("Sunrise/sunset event: ${evt.name}")
>     state.nighttime = isNighttime()
>     logDebug("Updated nighttime status: ${state.nighttime}")
>     
>     // If motion is currently active, check if we need to turn lamp on/off based on new day/night status
>     if (state.lastMotionActive) {
>         if (state.nighttime && toiletLamp.currentSwitch != "on") {
>             logDebug("Turning on lamp due to nighttime starting with active motion")
>             toiletLamp.on()
>         } else if (!state.nighttime && toiletLamp.currentSwitch == "on") {
>             logDebug("Turning off lamp due to daytime starting")
>             toiletLamp.off()
>         }
>     }
> }
> 
> def isNighttime() {
>     def sunriseTime = getSunriseWithOffset()
>     def sunsetTime = getSunsetWithOffset()
>     def now = new Date()
>     
>     if (sunriseTime.before(sunsetTime)) {
>         // Normal case - sunrise before sunset
>         return now.after(sunsetTime) || now.before(sunriseTime)
>     } else {
>         // Polar day/night cases
>         return now.after(sunsetTime) && now.before(sunriseTime)
>     }
> }
> 
> def getSunriseWithOffset() {
>     def sunrise = location.sunrise(timeZone: location.timeZone)
>     def offset = (sunriseOffset ?: 0) * 60 * 1000
>     return new Date(sunrise.time + offset)
> }
> 
> def getSunsetWithOffset() {
>     def sunset = location.sunset(timeZone: location.timeZone)
>     def offset = (sunsetOffset ?: 0) * 60 * 1000
>     return new Date(sunset.time + offset)
> }
> 
> def logDebug(msg) {
>     if (enableDebug) {
>         log.debug msg
>     }
> }
1 Like

Also, you may have missed my statement above about using the motion app. Sometimes using apps is much easier than trying to build rules for everything. But don't give up trying to learn how to do it.

A trigger of "motion active," which you have, is always active unless you do something in the rule to restrict it. From what we can see in your screenshot, you are not. (If there is more, like a required expression, they are important components of the rule that you need to include when sharing with others.)

You did appear to manually disable it for some reason, perhaps for testing. That is why it is in red and italics. That will never happen automatically; you would have done this in the editor yourself.

I would suggest writing a rule in one of the exact ways suggested to you above. The one you have is close, but as someone else suggested above, getting rid of the "motion active" condition in your actions should get you pretty close, if not exactly, to what you want. At this point, it seems like you are intentionally writing rules different from the ones suggested to you, perhaps because you want to tweak their logic. You may find that necessary eventually, but I would start with an exact example given to you to ensure you can get that working first.

If you do have problems, enable all logging for the rule and look at the output of Logs, filtered to just that rule. This will normally be very helpful for you to evaluate the flow of your logic and identify any problems -- or help someone else help you do the same if all else looks right (though it doesn't quite yet :slight_smile: ).

2 Likes

Hey Bert,

IT WORKS! :smile:

It took me a couple of hours this weekend, in between family stuff, but I got it working. At one point I finally saw it, just like you mentioned ā€œup thereā€. Maybe it’s because of how I translate everything in my head?
I always turn it into Dutch to make sense of it, since like I said English isn’t my native language.

And to be honest, I was getting a bit frustrated that I couldn’t get something like this to work, which made me even more stubborn about figuring it out.
I love learning new things, but to learn something, you have to understand it first and that was the tricky part for me here.

Thanks a lot for your patience and for answering my noob questions, Bert! :slightly_smiling_face: I’m gonna see what other things I can come up with now, ā€˜cause I’d like to dive a bit deeper into this.

Also, thanks to everyone else who jumped in to help — much appreciated!

P.S.: Yep, I did turn on logging to check where it was failing or stopping.

1 Like