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
- Device Selection:
- Choose a motion sensor to monitor
- Choose a lamp to control
- Time-Based Control:
- Only activates during nighttime (after sunset and before sunrise)
- Includes configurable sunrise/sunset offsets
- 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
- 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
- Debugging:
> 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
> }
> }