Accessing previous value (or maybe I'm holding it wrong)

I'm working on a rule that will control a virtual switch that represents the state of a washing machine based on a power monitoring plug. The base logic is essentially:

IF Power Level of Washer - Plug >= 25W for 1 minute THEN
    ON: Washer
ELSE IF Power Level of Washer - Plug < 25W for 2 minutes THEN
    OFF: Washer
END IF

Since I don't believe Rule Machine has a "stays true for duration' logical test I'm doing this via:

IF previousPower < 25 AND Power Level of Washer - Plug >= 25W THEN
    Cancel Delayed Actions
    Delay 1 minute (Cancel)
    ON: Washer
ELSE IF previousPower >= 25 AND Power Level of Washer - Plug < 25W THEN
    Cancel Delayed Actions
    Delay 2 minutes (Cancel)
    OFF: Washer
END IF
Set previousPower to Washer - Plug Power

Is there a better way beyond using local variables to track the previous state?

Here is a RM3.0 rule that does this

going to be a little more complicated in RM4.0 because your trigger will need to be if power level changes. Which it will a lot. So that rule will run many time while the power is changing. Not horrible, but the RM3 is simple.

You need to add Cancel to each of those delays.

Sorry, they do have cancels in the actual rule, I was transcribing them from memory.

I remembered the issue I had is the the delay prevents capturing the previous value. I think I need to rewrite with two local variables so the top of the rule can look like:

Set realPrevValue to prevValue
Set prevValue to Washer - Plug Power
// Do compares on realPrevValue

Delay 2 minutes Cancel

instead of what you have above.

Right, I just edited the original post to add those (they are in the actual rule). The problem again is actually that I need two local variables otherwise the prevValue doesn't get captured until after the delay triggers.

Based on my original post the sequence looks like:

T0.0: Event: Washer - Plug Power 50W
T0.1: IF previousPower(0) < 25 AND Power of Washer - Plug (50) >= 25 (TRUE)
T0.2: Cancel Delayed Actions
T0.3: Delay 1 minute (Cancel)
    // T0 Rule execution is now delaying here

T1.0: Event: Washer - Plug Power 75W
T1.1: IF previousPower(0) < 25 AND Power of Washer - Plug (75) >= 25 (TRUE)
    // previousPower should be 50 here but the delay for the T0 event prevented capture
T1.2: Cancel Delayed Actions
T1.3: Delay 1 minute (Cancel)
    // T1 Rule execution is now delaying here

My fix of having two state variables works, it is just a bit clunky. Any chance RM could expose a pre-trigger value for attributes?

Fixed flow:

T0.0: Event: Washer - Plug Power 50W
T0.1: Set realPreviousPower(0) = previousPower(0)
T0.2: Set previousPower(0) = Power of Washer - Plug (50)
T0.3: IF realPreviousPower(0) < 25 AND Power of Washer - Plug (50) >= 25 (TRUE)
T0.4: Cancel Delayed Actions
T0.5: Delay 1 minute (Cancel)
    // T0 Rule execution is now delaying here

T1.0: Event: Washer - Plug Power 75W
T1.1: Set realPreviousPower(0) = previousPower(50)
T1.2: Set previousPower(50) = Power of Washer - Plug (75)
T1.3: IF realPreviousPower(50) < 25 AND Power of Washer - Plug (75) >= 25 (FALSE)
    // T1 doesn't cancel the existing "turning on" delay

Is there a better approach to do this time-delay change detection besides using two local variables?