# String Items set using OnOffType ON will always appear to be OFF

**URL:** <https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174>\
**Category:** Scripts & Rules\
**Created:** [April 21, 2020, 3:26pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174 "2020-04-21T15:26:37Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [April 21, 2020, 3:26pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/1 "2020-04-21T15:26:37Z")

</div>

I’m using the expire timer to auto-shutoff a fan after a period of time (triggered by UI) in OH 2.5.2. I have a “Selection” component in habPanel where the user picks a period of time (10, 30, or 60 minutes). For each of those times, there is a corresponding item with a corresponding expire. When someone changes the item linked to the Selection control, a rule turns the fan and the timer “ON”.

However, for reasons surpassing my understanding, it seems that whenever one of these timers is turned on, it’s state shows as off.

Consider this code I created just to validate:

```auto
rule "Trying to understand tripped timers"
when
    Member of ThermostatTimers received command
then
    Thread::sleep(1000) 
    logInfo("Thermostats", "** Reporting Thermostat: {}", triggeringItem.name)
    logInfo("Thermostats", "** Reported state: {}", receivedCommand)
    logInfo("Thermostats", "** Actual state: {}", triggeringItem.state.toString)
    ThermostatTimers
        .members
        .forEach[ i |
            logInfo("Thermostats", "** Timer: {} State: {}", i.name, i.state.toString )
        ]
end

```

results in this:

```auto
** Reporting Thermostat: DownstairsThermostat_FanTimer_10
** Reported state: ON
** Actual state: OFF
** Timer: DownstairsThermostat_FanTimer_30 State: OFF
** Timer: DownstairsThermostat_FanTimer_60 State: OFF
** Timer: DownstairsThermostat_FanTimer_10 State: OFF

```

I’m baffled. Even more baffling, the fan _does_ turn off at the expected time!

Anybody have thoughts on what I should be looking for?

Thanks!

---

<div class="post-metadata">

**Author:** ![rossko57](https://community.openhab.org/user_avatar/community.openhab.org/rossko57/32/70263_2.png) [@rossko57](https://community.openhab.org/u/rossko57)\
**Post date:** [April 21, 2020, 3:52pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/2 "2020-04-21T15:52:18Z")

</div>

openHAB commands are asynchronous. Your rule runs before it has taken effect.

> [@Faulty, old value of Item within rule](https://community.openhab.org/t/faulty-old-value-of-item-within-rule/87664/2):
>
> Because commands are asynchronous. Any state update happens later.

Changed your rule trigger to `received update` to see the difference.  
It takes a while to get your head round an event-driven system.

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [April 21, 2020, 4:08pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/3 "2020-04-21T16:08:43Z")

</div>

> [@rossko57](#):
>
> openHAB commands are asynchronous. Your rule runs before it has taken effect.

That was my first thought too but there is a second sleep in there. That should be plenty of time for the Item to update to the new state.

> [@auzick](#):
>
> However, for reasons surpassing my understanding, it seems that whenever one of these timers is turned on, it’s state shows as off.

Look in events.log. What is the Item doing? Does it change to ON and then OFF right away or does it never turn OFF?

Do you have autoupdate=false configured on these Items? If so the Item will never update to ON in response to the command (useful when you get positive feedback from a device, not so useful for proxies or Expire timers like this).

---

<div class="post-metadata">

**Author:** ![Thedannymullen](https://community.openhab.org/user_avatar/community.openhab.org/thedannymullen/32/73361_2.png) [@Thedannymullen](https://community.openhab.org/u/Thedannymullen)\
**Post date:** [April 21, 2020, 4:31pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/4 "2020-04-21T16:31:44Z")

</div>

Can you post your items?

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [April 21, 2020, 5:24pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/5 "2020-04-21T17:24:53Z")

</div>

Here’s the log immediately after I select “10 minutes” in the UI:

```auto
2020-04-21 12:15:20.275 thru 12:15:20.465
Item 'DownstairsThermostat_FanTimer_Control' received command 10
DownstairsThermostat_FanTimer_Control changed from OFF to 10
Item 'DownstairsThermostatFanMode' received command 1
DownstairsThermostatFanMode predicted to become 1
Item 'DownstairsThermostat_FanTimer_10' received command ON
DownstairsThermostatFanMode changed from 0 to 1
DownstairsThermostat_FanTimer_Status changed from to Fan autoshutoff expected at 12:25.
DownstairsThermostatStatus changed from System: Idle. Fan: Off. Humidity: 46%. Battery: 95%. to System: Idle. Fan: Off. Humidity: 46%. Battery: 95%. Fan autoshutoff expected at 12:25.
DownstairsThermostatFanStateLiteral changed from Off to On
DownstairsThermostatFanState changed from 0 to 1

```

And here’s the items:

```auto
// MANUAL FAN TIMERS ----------------------------------------------------------------
// This item is expecting to receive a state of OFF, 10, 30, 60 or ON from a UI control.
String DownstairsThermostat_FanTimer_Control (TimedFanControls)
// These are the expiring items used to autoshutoff the fan.
String DownstairsThermostat_FanTimer_10 (ThermostatTimers) {expire="10m,command=OFF"}
String DownstairsThermostat_FanTimer_30 (ThermostatTimers) {expire="30m,command=OFF"}
String DownstairsThermostat_FanTimer_60 (ThermostatTimers) {expire="60m,command=OFF"}

String DownstairsThermostat_FanTimer_Status (DownstairsThermostat, ThermostatFanTimerStatus)

```

And if y’all are really willing to dig into it, here’s the relevant rules:

```auto

rule "Downstairs Thermostat Status String"
when
    Member of DownstairsThermostat changed
then
    var status = ""
    status += "System: " + transform("MAP", "thermostatoperatingstate.map", DownstairsThermostatOperatingState.state.toString) + ". "
    status += "Fan: " + DownstairsThermostatFanStateLiteral.state + ". "
    status += "Humidity: " + DownstairsThermostatHumidity.state + "%. "
    status += "Battery: " + DownstairsThermostatBattery.state + "%. "
    status += DownstairsThermostat_FanTimer_Status.state
    DownstairsThermostatStatus.postUpdate(status)
end

rule "ThermostatFanTimerStart"
when
    Member of TimedFanControls changed
then
    val thermostatName = triggeringItem.name.split("_").get(0)
    val fan = ThermostatFans.members.findFirst[l | l.name == thermostatName + "FanMode"]
    val time = triggeringItem.state

    if (fan === null){
        logInfo("Thermostats", "Attempt to start a timed fan cycled failed. No fan item found for {}", thermostatName)
        return;
    }

    var statusItem = ThermostatFanTimerStatus.members.findFirst[l | l.name == thermostatName + "_FanTimer_Status"]

    if (time == "OFF"){
        logInfo("Thermostats", "Turning off fan for {}.", thermostatName)
        fan.sendCommand(0);
        // clear the timer status string
        if (statusItem === null){
            logInfo("Thermostats", "Status item not found: {}{}", thermostatName, "_FanTimer_Status")
        } else {
            statusItem.postUpdate("")
        }
    } else if (time == "ON"){
        logInfo("Thermostats", "Turning on fan for {}.", thermostatName)
        fan.sendCommand(1);
        // clear the timer status string
        if (statusItem === null){
            logInfo("Thermostats", "Status item not found: {}{}", thermostatName, "_FanTimer_Status")
        } else {
            statusItem.postUpdate("")
        }
    } else {
        val timer = ThermostatTimers.members.findFirst[l | l.name == thermostatName + "_FanTimer_" + time]
        if (timer === null){
            logInfo("Thermostats", "Attempt to start a timed fan cycle failed. No {} minute timer found for {}", time, thermostatName)
            return;
        }
        logInfo("Thermostats", "Turning on {} (timed).", fan.name)
        fan.sendCommand(1);
        logInfo("Thermostats", "Tripping timer {}.", timer.name)
        timer.sendCommand(ON);

        ThermostatTimers
            .members
            .filter[i | i.name.contains(thermostatName) && ! i.name.contains(time.toString)]
            .forEach[ timerItem |
                if (timerItem.state.toString == "ON"){
                    logInfo("Thermostats", "Cancelling timer on {}", timerItem.name )
                    timerItem.sendCommand("OFF")
                } else {
                    logInfo("Thermostats", "Not cancelling timer on {} because it is {}", timerItem.name, timerItem.state.toString )
                }
            ]
    }
end

rule "ThermostatFanTimerTripped"
when
    Member of ThermostatTimers received command
then
    //logInfo("Thermostats", "ThermostatTimer {} received command {} and its state is {}", triggeringItem.name, receivedCommand.toString, triggeringItem.state.toString)
    if (receivedCommand.toString != "ON"){ return; }
    val minuteDelay = Integer.parseInt(triggeringItem.name.split("_").get(2))
    var shutoffTime = now.plusMinutes(minuteDelay)
    
    val thermostatName = triggeringItem.name.split("_").get(0)
    var statusItem = ThermostatFanTimerStatus.members.findFirst[l | l.name == thermostatName + "_FanTimer_Status"]
    logInfo("Thermostats", thermostatName + " fan autoshutoff expected at " + shutoffTime.toString("HH:mm"))
    statusItem.postUpdate("Fan autoshutoff expected at " + shutoffTime.toString("HH:mm") + ".")
end

rule "Trying to understand tripped timers"
when
    Member of ThermostatTimers received command
then
    Thread::sleep(1000) 
    logInfo("Thermostats", "** Reporting Thermostat: {}", triggeringItem.name)
    logInfo("Thermostats", "** Reported state: {}", receivedCommand)
    logInfo("Thermostats", "** Actual state: {}", triggeringItem.state.toString)
    ThermostatTimers
        .members
        .forEach[ i |
            logInfo("Thermostats", "** Timer: {} State: {}", i.name, i.state.toString )
        ]
end

rule "ThermostatFanTimerElapsed"
when
    Member of ThermostatTimers received command OFF
then
    logInfo("Thermostats", "Fan timer {} elapsed.", triggeringItem.name)
    val thermostatName = triggeringItem.name.split("_").get(0)
    //val timerDuration = triggeringItem.name.split("_").get(2)
    val fan = ThermostatFans.members.findFirst[l | l.name == thermostatName + "FanMode"]
    if (fan === null){
        logInfo("Thermostats", "Fan timer elapsed, but fan not found for {}", thermostatName)
        return;
    }

    //logInfo("Thermostats", "{} fan timer elapsed after {} minutes.", thermostatName, timerDuration)
    fan.sendCommand(0);

    // Update the proxy control item so UI will look right
    val control = TimedFanControls.members.findFirst[l | l.name == thermostatName + "_FanTimer_Control"]
    if (control === null){
        logInfo("Thermostats", "Fan timer elapsed, but UI control not found for {}", thermostatName)
    } else {
        control.postUpdate("OFF");
    }
end

```

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [April 21, 2020, 5:33pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/6 "2020-04-21T17:33:27Z")

</div>

I should also mention that I have dummy items in my habpanel for the timer items, and they always say “OFF”.

---

<div class="post-metadata">

**Author:** ![rossko57](https://community.openhab.org/user_avatar/community.openhab.org/rossko57/32/70263_2.png) [@rossko57](https://community.openhab.org/u/rossko57)\
**Post date:** [April 21, 2020, 6:23pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/7 "2020-04-21T18:23:13Z")

</div>

Please don’t strip timestamps out of your log snippets.

You’ve not shown your Group Items, but let’s assume they are defined.

> [@auzick](#):
>
> 2020-04-21 12:15:20.275 thru 12:15:20.465

Okay, that should not be long enough to get any output from the rule in the first post.

> [@auzick](#):
>
> Item ‘DownstairsThermostat\_FanTimer\_Control’ received command 10 DownstairsThermostat\_FanTimer\_Control changed from OFF to 10

Don’t know why that happened. Are you stripping out autoupdate predictions as well? Let’s guess so.

Meantime. `DownstairsThermostat_FanTimer_Control` is a member of `TimedFanControls`, so the rule “ThermostatFanTimerStart” runs due to the change.

That rule seeks Item `DownstairsThermostat_FanMode`  
(I don’t like the use of a variable called `time`, that looks like a reserved word perhaps.)  
That eventually gets commanded ‘1’

It also seeks an Item `DownstairsThermostat_FanTimer_Status`  
and an Item`DownstairsThermostat_FanTimer_10`  
and that gets commanded ON.  
Technically that’s an error, because it is a String type Item and you should command with a string “ON”, not an OnOffType ON.

Is that where we came in, `DownstairsThermostat_FanTimer_10` gets a command which starts expire timing, but it’s not a valid command so it doesn’t get reflected in state?

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [April 21, 2020, 6:38pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/8 "2020-04-21T18:38:56Z")

</div>

> [@auzick](#):
>
> 2020-04-21 12:15:20.275 thru 12:15:20.465

It really is quite helpful to see the actual timestamps on the log statements, especially if timing issues are one of the suspected causes for the bad behavior. It’s not only to see what events follow which events, but how long between the individual events.

In short, never redact stuff. We’d rather see more stuff than we need than less that we need.

It’s interesting that these are String Items. Any reason you are not using a Switch? You appear to be using it like a Switch.

> [@auzick](#):
>
> I should also mention that I have dummy items in my habpanel for the timer items, and they always say “OFF”.

Why do you have dummy Items for the timers?

Honestly this smells a whole lot like an XY Problem. What are you really trying to achieve? This seems way more complex than necessary. As best as I can tell, this would probably be better implemented using a Rule Timer and a single Number Item. Send 10, 30, or 60 to the one Number Item which triggers a Rule to set a Timer for that amount of time.

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [April 21, 2020, 7:33pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/9 "2020-04-21T19:33:00Z")

</div>

Point taken on the logs … I was trying to reduce clutter. Here’s another set of log entries, unredacted.

```auto
2020-04-21 13:41:33.655 [ome.event.ItemCommandEvent] - Item 'DownstairsThermostat_FanTimer_Control' received command 10
2020-04-21 13:41:33.657 [vent.ItemStateChangedEvent] - DownstairsThermostat_FanTimer_Control changed from OFF to 10
2020-04-21 13:41:33.671 [ome.event.ItemCommandEvent] - Item 'DownstairsThermostatFanMode' received command 1
2020-04-21 13:41:33.671 [nt.ItemStatePredictedEvent] - DownstairsThermostatFanMode predicted to become 1
2020-04-21 13:41:33.673 [ome.event.ItemCommandEvent] - Item 'DownstairsThermostat_FanTimer_10' received command ON
2020-04-21 13:41:33.679 [vent.ItemStateChangedEvent] - DownstairsThermostatFanMode changed from 0 to 1
2020-04-21 13:41:33.681 [vent.ItemStateChangedEvent] - DownstairsThermostat_FanTimer_Status changed from to Fan autoshutoff expected at 13:51.
2020-04-21 13:41:33.685 [vent.ItemStateChangedEvent] - DownstairsThermostatStatus changed from System: Idle. Fan: Off. Humidity: 46%. Battery: 95%. to System: Idle. Fan: Off. Humidity: 46%. Battery: 95%. Fan autoshutoff expected at 13:51.
2020-04-21 13:41:33.821 [vent.ItemStateChangedEvent] - DownstairsThermostatFanStateLiteral changed from Off to On
2020-04-21 13:41:33.821 [vent.ItemStateChangedEvent] - DownstairsThermostatFanState changed from 0 to 1
2020-04-21 13:41:33.826 [vent.ItemStateChangedEvent] - DownstairsThermostatStatus changed from System: Idle. Fan: Off. Humidity: 46%. Battery: 95%. Fan autoshutoff expected at 13:51. to System: Idle. Fan: On. Humidity: 46%. Battery: 95%. Fan autoshutoff expected at 13:51.

```

> [@rossko57](#):
>
> Don’t know why that happened. Are you stripping out autoupdate predictions as well? Let’s guess so.

No, the only thing I redacted was the time and source from the log entries. What do you mean by “autoupdate predictions”? The entries that say `predicted to become...`? I never really understood that.

> [@rossko57](#):
>
> Meantime. `DownstairsThermostat_FanTimer_Control` is a member of `TimedFanControls` , so the rule “ThermostatFanTimerStart” runs due to the change.

Intended. This “Control” is a proxy for a user interface item. This is the rule that turns the fan on or off, and sets the autoshutoff timer if needed (along with some housekeeping like creating status strings, and “cancelling” any other timer that might be running).

> [@rossko57](#):
>
> That rule seeks Item `DownstairsThermostat_FanMode`  
> (I don’t like the use of a variable called `time` , that looks like a reserved word perhaps.)  
> That eventually gets commanded ‘1’

Yes, the Honeywell thermostat uses a number of the fan mode: 0=Auto, 1=On, 2=Circulate (a predefined timed fan cycle). Agreed on the bad variable name.

> [@rossko57](#):
>
> It also seeks an Item `DownstairsThermostat_FanTimer_Status`  
> and an Item `DownstairsThermostat_FanTimer_10`  
> and that gets commanded ON.  
> Technically that’s an error, because it is a String type Item and you should command with a string “ON”, not an OnOffType ON.

and

> [@rlkoshak](#):
>
> It’s interesting that these are String Items. Any reason you are not using a Switch? You appear to be using it like a Switch.

I didn’t need to use Strings here; a Switch would have done. I patterned after a different use case where I needed to differentiate between a “rule” `ON` and a “device” `ON`, so I had rules posting a `RESET` to it which in turn tripped a rule to turn it on. Not as elegant as @rlkoshak’s design pattern for that purpose, which I use extensively (and extended to include motion sensors and manage autoshutoff).

As far as `ON` vs `"ON"` issue, I realize I’ve been inconsistent. In my head, things like `ON` and `OFF` are just enumerations representing strings. My c# thinking, there, and apparently wrong in this context.

> [@rossko57](#):
>
> Is that where we came in, `DownstairsThermostat_FanTimer_10` gets a command which starts expire timing, but it’s not a valid command so it doesn’t get reflected in state?

And we have a winner! That’s at least part of my problem … changing all the `ON/OFF` to `"ON"/"OFF"` is having an effect! I need to clean up some other stuff, but that was very helpful!

> [@rlkoshak](#):
>
> Why do you have dummy Items for the timers?

Just while troubleshooting, so I could see the state of those timer items.

> [@rlkoshak](#):
>
> Honestly this smells a whole lot like an XY Problem. What are you really trying to achieve? This seems way more complex than necessary. As best as I can tell, this would probably be better implemented using a Rule Timer and a single Number Item. Send 10, 30, or 60 to the one Number Item which triggers a Rule to set a Timer for that amount of time.

Yes, this become more complex than I expected. I’ve had problems using timers in other rules. Not really understanding the scope or threading of those timers, I wound up with all kinds of unexpected results when I tried “resetting” them, or turning them “off”. After reading and using the “Proxy Item” approach in your [Manual Trigger Detection](https://community.openhab.org/t/design-pattern-manual-trigger-detection/32937) design pattern, I became enamored of the approach of allowing a proliferation of items to overcome complex rules code. I asked myself why I couldn’t do that for this use case, but I wound up with complex rules code anyway. I guess I need to sharpen my understanding of timers and refactor this.

Thanks to you both for the thoughtful responses!

---

<div class="post-metadata">

**Author:** ![rossko57](https://community.openhab.org/user_avatar/community.openhab.org/rossko57/32/70263_2.png) [@rossko57](https://community.openhab.org/u/rossko57)\
**Post date:** [April 21, 2020, 7:38pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/10 "2020-04-21T19:38:49Z")

</div>

If you’re sticking with DSL rules for now, you may be interested in -

> [@Design Pattern : Expire Binding based Countdown timer](https://community.openhab.org/t/design-pattern-expire-binding-based-countdown-timer/49225):
>
> Problem Statement Sometimes you need to run a timer, but want to able to inspect the remaining time. This is not directly possible with either createTimer() or the Expire binding. Example - I have lighting-on timers that run for different duration depending on the trigger source or time of day. It is useful to have the timer behave “intelligently” - do not apply a new 5-minute request where there is still seven minutes of a previous trigger to run. But do apply it if there is only two minu…

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [April 21, 2020, 7:56pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/11 "2020-04-21T19:56:30Z")

</div>

> [@rossko57](#):
>
> If you’re sticking with DSL rules for now

Subtle. I went into this using the Rules DSL because

1. I saw more examples out there using the DSL than python, and I’m a Google-dependent developer, and
2. I suck at python.

The latter problem being borne of the same laziness that makes me a Googler. I’ve learned many, many languages to greater or lesser degrees over the decades since I started with COBOL. Right now, my highest proficiency language is .net core c#, and to a lesser degree, the rest of a .net world web development stack. Maybe I need to move along here and get my head around this newfangled python stuff 🙂.

Thanks for the link … I’ll read it.

---

<div class="post-metadata">

**Author:** ![rossko57](https://community.openhab.org/user_avatar/community.openhab.org/rossko57/32/70263_2.png) [@rossko57](https://community.openhab.org/u/rossko57)\
**Post date:** [April 21, 2020, 7:59pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/12 "2020-04-21T19:59:19Z")

</div>

> [@auzick](#):
>
> No, the only thing I redacted was the time and source from the log entries. What do you mean by “autoupdate predictions”?

Now I recall that autoupdate does not log it’s predictions unless the Item concerned has a binding linked, so that’s sorted.

> [@auzick](#):
>
> The entries that say `predicted to become...` ? I never really understood that.

This might help

> [@Faulty, old value of Item within rule](https://community.openhab.org/t/faulty-old-value-of-item-within-rule/87664/7):
>
> The underlying model of openHAB - An Item is our model of some external device - let’s say, a roller blind. You might send it a command from a rule or UI. Let’s say you command “UP”. The command passes through bindings and communication methods to the device. The device actions the command and passes it’s new status back through comms and binding etc. Eventually that results in the Item state being updated, say to “80%”. Maybe after a while longer it will send again, “90%”. In order to w…

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [April 21, 2020, 8:09pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/13 "2020-04-21T20:09:20Z")

</div>

> [@auzick](#):
>
> No, the only thing I redacted was the time and source from the log entries. What do you mean by “autoupdate predictions”? The entries that say `predicted to become...` ? I never really understood that.

There is a feature of OH called `autoupdate`. This is a sort of pseudo-binding that, when configured as true on an Item (the default) will take any command sent to that Item and attempt to predict what state the Item will become in response to the command. It has to predict because not all commands become a state. For example, consider a Dimmer. You might `sendCommand(INCREASE)` and `autoupdate` may predict the new state will become `75`. `autoupdate` is required when you have devices that do not report back when you’ve commanded them to do something. For Expire based bindings, you would want to keep `autoupdate` set to true because I think it’s the update that causes the Expire binding timer to kick off. Sending a command with `autoupdate` set to false means the Item never receives and update.

The lack of the “autoupdate predicts” log statements would indicate that `autoupdate=false`, though that doesn’t appear to be the case given your Item definitions.

> [@auzick](#):
>
> Not really understanding the scope or threading of those timers, I wound up with all kinds of unexpected results when I tried “resetting” them, or turning them “off”.

When you call `createTimer`, a “handle” on the Timer is returned. You can store that as a global variable and thus access a Timer created in another Rule or a previous run of the same Rule. Then you can use the variable to cancel or reschedule the Timer. If you have generic Rules, you can use a Map\<String, Timer\> to store the Timers in a HashMap and therefore access a timer based on `triggeringItem.name`, for example.

As for threading, Timers do not consume any threads while waiting to run. When they trigger, they consume a thread while the code is executing from the Quartz Timer thread pool. There are 10 threads in this pool so you can have up to ten Timer actively running at the same time.

> [@rossko57](#):
>
> If you’re sticking with DSL rules for now, you may be interested in -

I converted that to a Python library as well. See [Initial submission of a Countdown Timer implementation by rkoshak · Pull Request #237 · openhab-scripters/openhab-helper-libraries · GitHub](https://github.com/openhab-scripters/openhab-helper-libraries/pull/237/commits). It doesn’t use Expire binding but it does all the timer management for you anyway so that doesn’t really matter. Just call the function with the amount of time, the Item you want to get updated as it counts down, and the lambda to call when the timer goes off.

> [@auzick](#):
>
> I suck at python.

How are you with JavaScript or Groovy? Both of those are also supported as well. Though you don’t have to be a Python coder to write Python OH Rules. Very rarely do we need to go that deep into specifics of the language. And I believe I’ve written Python examples for all of the Design Patterns, at least those that are applicable.

> [@rossko57](#):
>
> Now I recall that autoupdate does not log it’s predictions unless the Item concerned has a binding linked, so that’s sorted.

I didn’t know that. That’s good information to know. But the Expire binding is linked, right?

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [April 21, 2020, 8:29pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/14 "2020-04-21T20:29:30Z")

</div>

I’ve been told my javascript looks like it was written like this: [https://gifer.com/embed/DwzE](https://gifer.com/embed/DwzE)

> [@rlkoshak](#):
>
> converted that to a Python library as well.

Can you point me to an example where you’ve used that from openHab? You may be assuming too much about my familiarity with all this.

Again, thanks!  
Andy

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [April 21, 2020, 8:40pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/15 "2020-04-21T20:40:42Z")

</div>

You have to [install Python](https://community.openhab.org/t/beta-testers-wanted-jython-addon-w-helper-libraries-requires-oh-2-5-x/86633) and then copy the code at that link to `$OH_CONF/`. Then look at the test code which shows how to use it.

---

<div class="post-metadata">

**Author:** ![rossko57](https://community.openhab.org/user_avatar/community.openhab.org/rossko57/32/70263_2.png) [@rossko57](https://community.openhab.org/u/rossko57)\
**Post date:** [April 22, 2020, 9:32am UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/16 "2020-04-22T09:32:18Z")

</div>

> [@rlkoshak](#):
>
> That’s good information to know. But the Expire binding is linked, right?

I’ve re-discovered the suppressed autoupdate prediction messages at least three times now and forgotten until the next time …

In this case, the Item was DownstairsThermostat\_FanTimer\_Control which is not linked to expire, or anything else.  
I am not entirely sure if autoupdate recognises v1.x links for this suppression purpose though.

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [May 4, 2020, 2:30pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/17 "2020-05-04T14:30:11Z")

</div>

> [@rlkoshak](#):
>
> You have to [install Python](https://community.openhab.org/t/beta-testers-wanted-jython-addon-w-helper-libraries-requires-oh-2-5-x/86633) and then copy the code at that link to `$OH_CONF/` . Then look at the test code which shows how to use it.

Thank! found [documentation page](https://www.openhab.org/docs/configuration/jsr223-jython.html) references Jython 2.7.0. Should I do that first? I’d like to get into this to have a better devex for OH, but I’m afraid I’m out over my skis.

Note that I’m on OH 2.5.2 on Windoze…

Thanks.

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [May 4, 2020, 3:01pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/18 "2020-05-04T15:01:22Z")

</div>

You are better off starting with the link I posted above in post 15. Following those instructions will install Jython and the helper libraries that makes writing OH Rules much simpler.

---

<div class="post-metadata">

**Author:** ![auzick](https://community.openhab.org/user_avatar/community.openhab.org/auzick/32/44650_2.png) [@auzick](https://community.openhab.org/u/auzick)\
**Post date:** [May 4, 2020, 3:02pm UTC](https://community.openhab.org/t/string-items-set-using-onofftype-on-will-always-appear-to-be-off/97174/19 "2020-05-04T15:02:01Z")

</div>

Good to hear … thanks!
