Create timers triggered by command or status change of a device

Hi everyone.

Some weeks ago I literally broke my SD card of my Raspi 3 without having backups. #lesson-learned :melting_face:
So I set everything up again and created some rules which I want to share with you.

Problems:

  1. My coffee machine needs some time to start/heat up.
  2. It turns into standby after some time and needs a button press to reactivate. The standby preventing the start/heat up.

Idea:

  1. I add a power plug (Sonoff S26 with Tasmota) to turn it on from my bed. :wink:
  2. I turn off the coffee machine after amount of time to prevent standby.

Approche:

  • Two timers
    • turning it off
    • send notification via Echo device
  • Reschedule/prolong timers if I send again an ON command
  • Stop both timers when machine is turned off manually.

Code: coffeetimer.rule

import org.openhab.core.model.script.ScriptServiceUtil

val Echo_Location = "Kitchen" // Kitchen / Bed_Room / Bath_Room / Floor
val Echo_Vol = 20
var long ausZeit = 15 // time to turn off
var long warnungZeit = 5 // time to warn before turning of
var long verlaengerungZeit = 10 // time when timer is extended
var Timer TimerKaffeemaschinenAus = null
var Timer TimerKaffeemaschinenWarnung = null

rule "Kaffeemaschinen command"
when
    Item KaffeemaschinePowerSwitch received command or
    Item KaffeemaschinePowerSwitch changed
then
    // early return if diff is negative or zero
    if(ausZeit <= warnungZeit) {
        logError("rule.Kaffee", "ausZeit <= warnungZeit")
        return;
    }
    if(verlaengerungZeit <= warnungZeit) {
        logError("rule.Kaffee", "verlaengerungZeit <= warnungZeit")
        return;
    }
    val warnungDiffZeit = ausZeit - warnungZeit
    val verlaengerungDiffZeit = verlaengerungZeit - warnungZeit
    val Echo_TTS = ScriptServiceUtil.getItemRegistry.getItem("Echo_" + Echo_Location + "_TTS") as GenericItem
    val Echo_TTS_Vol = ScriptServiceUtil.getItemRegistry.getItem("Echo_" + Echo_Location + "_TTS_Vol") as GenericItem

    if(receivedCommand !== null && KaffeemaschinePowerSwitch.state.toString === receivedCommand.toString) {
        if(receivedCommand === ON) {
            logDebug("rule.Kaffee", "command AGAIN " + receivedCommand.toString)
            if (TimerKaffeemaschinenAus !== null) {
                logInfo("rule.Kaffee", "Timer erneuert: plus " + verlaengerungDiffZeit.toString)
                TimerKaffeemaschinenAus.reschedule(now.plusMinutes(verlaengerungDiffZeit))
            }
            if (TimerKaffeemaschinenWarnung !== null) {
                logInfo("rule.Kaffee", "Warnung erneuert: plus " + verlaengerungDiffZeit.toString)
                TimerKaffeemaschinenWarnung.reschedule(now.plusMinutes(verlaengerungDiffZeit))
            } else {
                TimerKaffeemaschinenWarnung = createTimer(now.plusMinutes(warnungDiffZeit), [ |
                    logInfo("rule.Kaffee", "Warnung abgelaufen: nach " + warnungZeit.toString)
                    var previousVol = Echo_TTS_Vol.state as Number
                    Echo_TTS_Vol.sendCommand(Echo_Vol)
                    Echo_TTS.sendCommand('<speak>Noch ' + warnungZeit + ' Minuten.</speak>')
                    Echo_TTS_Vol.sendCommand(previousVol)
                ])
                logInfo("rule.Kaffee", "Warnung erstellt: für " + warnungDiffZeit.toString)
            }
        }
    }
    if(newState !== null) {
        logDebug("rule.Kaffee", "change " + newState.toString)
        if(newState === ON) {
            if (TimerKaffeemaschinenAus !== null) {
                logInfo("rule.Kaffee", "Timer erneuert: plus " + verlaengerungZeit.toString)
                TimerKaffeemaschinenAus.reschedule(now.plusMinutes(verlaengerungZeit))
                var previousVol = Echo_TTS_Vol.state as Number
                Echo_TTS_Vol.sendCommand(Echo_Vol)
                Echo_TTS.sendCommand('<speak>Plus ' + verlaengerungZeit + ' Minuten.</speak>')
                Echo_TTS_Vol.sendCommand(previousVol)
            } else {
                TimerKaffeemaschinenAus = createTimer(now.plusMinutes(ausZeit), [ |
                    logInfo("rule.Kaffee", "Timer abgelaufen: nach " + ausZeit.toString)
                    KaffeemaschinePowerSwitch.sendCommand(OFF)
                ])
                logInfo("rule.Kaffee", "Timer erstellt: für " + ausZeit.toString)
                var previousVol = Echo_TTS_Vol.state as Number
                Echo_TTS_Vol.sendCommand(Echo_Vol)
                Echo_TTS.sendCommand('<speak>' + ausZeit + ' Minuten.</speak>')
                Echo_TTS_Vol.sendCommand(previousVol)
            }
            if (TimerKaffeemaschinenWarnung !== null) {
                logInfo("rule.Kaffee", "Warnung erneuert: plus " + verlaengerungDiffZeit.toString)
                TimerKaffeemaschinenWarnung.reschedule(now.plusMinutes(verlaengerungDiffZeit))
            } else {
                TimerKaffeemaschinenWarnung = createTimer(now.plusMinutes(warnungDiffZeit), [ |
                    logInfo("rule.Kaffee", "Warnung abgelaufen: nach " + warnungDiffZeit.toString)
                    var previousVol = Echo_TTS_Vol.state as Number
                    Echo_TTS_Vol.sendCommand(Echo_Vol)
                    Echo_TTS.sendCommand('<speak>Noch ' + warnungZeit + ' Minuten.</speak>')
                    Echo_TTS_Vol.sendCommand(previousVol)
                ])
                logInfo("rule.Kaffee", "Warnung erstellt: für " + warnungDiffZeit.toString)
            }
        } else if(newState === OFF) {
            logInfo("rule.Kaffee", "- - - - - - - - - - - - -")
            if (TimerKaffeemaschinenAus !== null) {
                logInfo("rule.Kaffee", "Timer cancled")
                TimerKaffeemaschinenAus.cancel
                TimerKaffeemaschinenAus = null
            }
            if (TimerKaffeemaschinenWarnung !== null) {
                logInfo("rule.Kaffee", "Warnung cancled")
                TimerKaffeemaschinenWarnung.cancel
                TimerKaffeemaschinenWarnung = null
            }
            logInfo("rule.Kaffee", "- - - - - - - - - - - - -")
        }
    }
end

I know, it looks a bit messy, bit this comes with the problem that the rule received no command when the button of the power plug is pressed manually. :face_with_peeking_eye:

If someone has an any suggestions for improvement I will really appreciate!

1 Like

If I get your requirement right you don’t need a rule. I use an expiration timer on the Item-Definition:

Regardless of how I switch on the printer (via OpenHab, HomeKit or directly at the switchable plug). OpenHab will set it to OFF after four hours.

1 Like

Thanks for your reply.
You got it right, but you missed that I want timer status info and get a notification when the coffee machine will turn off soon. This is because I don’t want to get it powered down when it is actually making a coffee. :coffee:

I also want to prolong my timers when I know OH will power down the machine soon. Therefor I will ask Alexa to turn on the coffee machine (again).

1 Like

This works for Switch but not all commands correspond to the Item’s state. For example, you can command ON/OFF, INCREASE/DECREASE to a Color or a Dimmer Item but the state will never match these commands. It’s just something to be aware of.

Because you don’t ever look at the state of this Item, you don’t really have to pull it here. You could use the sendCommand(ItemName, Command) Action instead.

You still might be able to simplify the rule using the Expire binding. You can still create the Timer to send the notification when the coffee machine will turn off soon in your rule but let Expire turn off the coffee machine itself. When you command it ON again, that will reset the Expire timer. The command will even retrigger the warning rule so your notification timer can be rescheduled too.

One fewer timers to manage here could cut out roughly 25% of the code in this rule.

1 Like

Thanks for your reply.

Thanks, missed that :+1:

Interesting idea. I will try it and create a second item for the warning.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.