Perpetual timer?

I am trying to set-up a timer that sets itself after expiry… if this makes sense.

I have a cron rule at 15:00 setting up this timer:

    timerLateArvoChargeDecrement = createTimer(now.plusMinutes(60)) [|
      spp_GridSupportChargeAdjust.postUpdate((spp_GridSupportChargeAdjust.state as Number) - 5)
      logInfo("spp_GridSupportChargeAdjust.rule", "spp_GridSupportChargeAdjust = {}", spp_GridSupportChargeAdjust.state)
      timerLateArvoChargeDecrement = null

… its job is to discount (decrement) by 5.

Once it has expired = done the decrement, I want it to continue (as in doing this every hour), until another rule kills the timer based on some if condition.

some background: on not so sunny days, the battery may not get charged to a desired level… in this case 90%. So at 15:00 it checks do we have 90%, if not, we charge from the grid.
This charging takes time, dependent on the actual SOC.
After 16:00 the SOC declines almost linear by 5% per hour – hence the timer.
There is no point in charging the battery to 100% given the possibility that the sun will shine the next day and then charge the battery for free.
Hence, the reduction of the charge level per timer, 5% less every hour.
I could do a timer for 1% every 12 minutes to achieve the same outcome, just more granular.

I could have set another timer, but this does not sound right to me… kicking off many timers.

I could use a cron rule 0/12, if charge == on decrement by 5, and stop the charge once hitting the new target.

Any elegant solutions out there?

A recursive Timer ?

‘elegant’ is too strong perhaps, this kind of thing is headache inducing, be warned.

1 Like

Should have guessed it that Rich had solved this before :slight_smile:
You too by the looks of it…

Though way over my head :frowning:

I think I ditch the timer and go with a 12 minute cron with an if charging on -=5, else do nothing. and flick the charging state. Don’t care if cron runs 24h.

The 90% value will be reset to 90% at 15:00…

I have a crack it it… sounds simple an doable :slight_smile:

It is probably a lot simpler. You likely don’t care about cron based side effects, like the “next 12-min run” actually coming up 1 to 12 mins after some other event X (sunset etc.)

Thanks for caring…

No it is not effecting something else; this is a crude but sufficient method to avoid charging the battery beyond its SOC is usually has later in the day.

It probably helps to know that my 20kWh battery is usually charged between 10:00 and 12:00 every normal sunny day – which we have lots of (here in Queensland Australia). I may have less than 25 days, where the battery does not get charged to a 100%… this is where the 15:00 90% SOC comes in.

90% because I get easily away with 90% instead of 100% SOC…
As stated before, from 16:00 onwards I use almost linear 1% SOC per 12 minutes or 5 per hour.
Depending on how low the SOC is, charging (at no more than 5kW/h) may take some time, during which the SOC would normally be lower, hence, I can limit charging to that lower value… I hope this makes sense.

The rule I implemented is this:

// ----- 170615 MaxG: reduce charge rate by 1% every 12 minutes
rule "SP PRO GO: reduce charge rate by 1% every 12 minutes"
    //         s m    h     D M DoW Y
    Time cron "0 0/12 16-20 * * ? *"
    // here: every 12 minutes, between 16:00 and 20:59
    if (spp_GridSupportLateArvo.state == ON) {
      spp_GridSupportChargeAdjust.postUpdate((spp_GridSupportChargeAdjust.state as Number) - 1)
      logInfo("ChargeAdjust.rule", "spp_GridSupportChargeAdjust = {}", spp_GridSupportChargeAdjust.state)

I was simply thinking to complicated (or not at all) :slight_smile:

The elegant solution I think is your cron rule. It is simple, easy to understand, and easy to write.

However, the version that uses the Expire binding isn’t too bad. You would use a Switch (in the example FrontDoor_Timer) with Expireas the Timer and a rule that triggers when the timer goes to OFF would contain the body of the Timer. Rescheduling the Timer is as simple as calling FrontDoor_Timer.sendCommand(ON).

Still not as simple as using the cron but certainly not as hard as creating a Timer from within the body of the Timer. That leads to a “turtles all the way down” problem which the original solution in that link solves by using a lambda.