Autoupdate - a primer

Tags: #<Tag:0x00007f617be52930> #<Tag:0x00007f617be52340>

I’ve found myself having to investigate and/or explain some of the features of autoupdate over time, and thought an in-depth view would be helpful.

These notes apply to openHAB version 2.5

Overview

Autoupdate is primarily a “speed up” feature for openHAB Items. Mostly we can ignore it, but sometimes you may get an unwanted or unexpected effect, or you may wish to exercise more control.
To fully understand autoupdate, we must understand the difference between command and state of Items.

If we look at the basic flow of Item based activities -

  • An Item may receive a command from the User clicking a screen, or programmatically from a rule, etc. That command will not directly affect the Item state.
  • The command will be passed to any linked bindings, and so onwards to an external device or service.
  • Later, the device may respond announcing its new status. The binding processes that into a state update of the original Item.

It is clear that all takes time. Depending on the kind of device, it could take a second or more from a “click” to an apparent onscreen response. That makes for a horrible user experience, as we all expect something to happen visually immediately.

This is where autoupdate comes in. By acting like a “rapid response” binding, it avoids that delay. So re-stating our workflow with autoupdate active –

  • Item receives command from the user clicking, or rule, etc. That command will not directly affect the Item state.
  • The command will be passed to any linked bindings, and so onwards to any external device.
  • It also gets passed to autoupdate. Autoupdate predicts the likely outcome of the command.
  • Autoupdate (usually) issues the prediction as an immediate update to the Item state.
  • Later, the device may respond announcing its new status. The binding processes that into another state update of the original Item (but autoupdate may have already set the same state).

It looks more complicated, but as it takes only a few milliseconds for autoupdate to make its prediction, the response time at the User interface appears instant…

Secondary effect for unlinked or write-only Items

From the command-state workflow that we noted earlier, you can see that an Item linked to no bindings, or to a write-only device that never responds with status, would never get a new state as a result of any command.

Allowing autoupdate to apply its predictions here neatly overcomes this problem, so in that most cases our Item state will respond to a command, even when no “real” state update is available.

Control of autoupdate

As outlined, autoupdate is a feature that applies at the Item level.
By default, autoupdate is enabled for all Items.
It is possible to disable or to force autoupdate on individual Items.

For Items defined in OH1 style items files, this is done in the {bindings} configuration section, as might be expected for a kind of pseudo-binding.

Switch bedroom "Bedroom light" <light> {channel="blah:bleh", autoupdate="false"}

For Items defined in PaperUI, editing the Item will offer an autoupdate selection box, with “enforce” or “veto” options (equivalent to false and true).

Not specifying true/false (or enforce/veto) leaves autoupdate in default mode, which is not quite the same as forcing it; see later notes.

Limitations

Autoupdate is not all-powerful and all-knowing.

Consider a Dimmer type Item -

  • We may send this numeric commands, like 75 for 75% brightness.
    Autoupdate responds as you might expect, and predicts 75 for Item state.
  • We may send ON/OFF commands. A real dimmer may come on at its last set brightness, but autoupdate knows nothing of that, because it only works with the Item.
    Autoupdate responds with its best guess, and when commanded ON predicts 100 for Item state, which may turn out not to be accurate.
  • We may send INCREASE/DECREASE commands, a real dimmer may respond with 1 or 5 or 10% steps depending on configuration, or may not implement this at all - but again autoupdate knows nothing of this.
    In this case, autoupdate cannot make any likely guess – and so does not make a prediction at all.

Events – prediction and update

So far you might assume an autoupdate prediction and Item update are much the same thing, but in fact they appear on openHABs event bus as two separate event types.
In some circumstances, you may get one or the other, both or none.

A prediction event can be listened for by a UI (remember why we have autoupdate at all) and so can be used to provide the fast-updating display - but without going on to actually update the Item. That is sensible if we expect a prompt “real” update from a device. By avoiding an extra state update, we cut down on event bus traffic, rule triggers, persistence records.

Logging

You will sometimes see autoupdate produced entries in your events.log, showing the events just described.

Observations -

  • Predictions (if enabled) are normally logged for Items with one or more bindings.
  • Predictions are not logged for Items with no bindings. If autoupdate is enabled, it will just do its thing and logging is superfluous.
  • Predictions are not logged when autoupdate is forced, again it would be superfluous.
  • Item updates are normally not logged. A state update may cause an Item state change – that will be logged.

“Jitter” or "Jumping"

Sometimes autoupdate produces odd noticeable effects.

Real devices linked to openHAB Items, such as dimmers and rollershutters, may take time to respond to commands. They may issue “progress reports” as they carry out a command over time, e.g. a moving roller might update its Item with position 70%, then 60%, then 50% etc.

A sample events.log, with default autoupdate at work on this Item

2018-11-24 18:28:26.818 [ome.event.ItemCommandEvent] - Item 'RS_RollerShutter_01' received command UP
2018-11-24 18:28:26.823 [nt.ItemStatePredictedEvent] - RS_RollerShutter_01 predicted to become UP
2018-11-24 18:28:26.827 [vent.ItemStateChangedEvent] - RS_RollerShutter_01 changed from 27 to 100
2018-11-24 18:28:28.407 [vent.ItemStateChangedEvent] - RS_RollerShutter_01 changed from 100 to 35
2018-11-24 18:28:45.606 [vent.ItemStateChangedEvent] - RS_RollerShutter_01 changed from 35 to 100

As you can see, autoupdate’s simplistic prediction of a 100 result from UP command is applied immediately, but the later response from the still moving roller is 35, and then later still 100.
State sequence 27 -> 100 -> 35 -> 100

On a UI screen, this can appear as an odd “jumping” effect.
If you find that unpleasant, simply disable autoupdate for that Item.

Sample events log, with autoupdate disabled -

2018-11-24 18:28:26.818 [ome.event.ItemCommandEvent] - Item 'RS_RollerShutter_01' received command UP
2018-11-24 18:28:28.407 [vent.ItemStateChangedEvent] - RS_RollerShutter_01 changed from 27 to 35
2018-11-24 18:28:45.606 [vent.ItemStateChangedEvent] - RS_RollerShutter_01 changed from 35 to 100

Similar “jittery” behaviour can be encountered with dimmers that take time to ramp up/down to a new setting.

It can also sometimes be observed with some devices that respond to a command with their current state, i.e. the “old” status, before implementing the command and then later providing another status update.
This can result in a “jumping” sequence like
existing -> prediction -> existing -> new
which again you may choose to suppress by disabling autoupdate.

A similar effect may occasionally appear when using polling bindings, like Modbus, when a scheduled read may occur just before the requested write.

In summary - where you know you will get a timely and accurate status update from a device, you can choose not to use autoupdate.

Binding/channel “interference”

There is a further complication, in that bindings can influence results. Autoupdate will ask any channels linked to the Item for an “second opinion” about proposing a prediction. Remember, autoupdate is only guessing at likely results of a command. A binding “knows” more about the target device, and is allowed to control autoupdate to an extent.

A binding channel may set one of three autoupdate policies for action.

  • Default – “If you like”. Most channels currently have this mode, allowing autoupdate to make its usual predictions.
  • Recommend – “Yes please”. For example, the binding may know a device is write-only, there will never be real status feedback. Autoupdate is requested to take action, to perform an Item update.
  • Veto – “No thanks”. For example, the binding may know a device is broken (the configuration is faulty, perhaps), so the command cannot be carried out, no prediction or update is wanted.

Autoupdate takes any linked channels policy setting into account when considering its action.

This was a relatively new feature at openHAB 2.4 onwards, and more bindings may exploit it in future.
Version 1.x bindings have no channels, and are ignored by autoupdate for this purpose.

There are some consequences here – an invalid channel link falls into the category of “this cannot work”, and so a veto is applied. So, note that a mistake in your Item config can prevent autoupdate working.

9 Likes

Examples

Autoupdate turns out to be more subtle than first appears, and examples of various situations should help clarify how it acts.

Unlinked Item, autoupdate left enabled as default.

This is a common usage for “virtual” Items

Dimmer testDim "dimmer [%s]"

events.log

2020-06-28 01:23:02.370 [ome.event.ItemCommandEvent] - Item 'testDim' received command 75
2020-06-28 01:23:02.380 [vent.ItemStateChangedEvent] - testDim changed from NULL to 75

2020-06-28 01:23:13.831 [ome.event.ItemCommandEvent] - Item 'testDim' received command ON
2020-06-28 01:23:13.841 [vent.ItemStateChangedEvent] - testDim changed from 75 to 100

2020-06-28 01:23:24.838 [ome.event.ItemCommandEvent] - Item 'testDim' received command DECREASE

Here we can see that –

  • autoupdate does not log a prediction when there are no bindings
  • autoupdate sometimes guesses – 100 for ON
  • autoupdate sometimes has no idea – no guess made for DECREASE

Unlinked Item, with autoupdate disabled

Dimmer testDim "dimmer [%s]" {autoupdate="false"}
2020-06-28 01:32:47.285 [ome.event.ItemCommandEvent] - Item 'testDim' received command 75

Here we see no response.

Sometimes useful when commands and states are exploited separately by rules. We can have a rule triggered from command, and do what we like with state – or do nothing at all.

Linked Item, with default channel autoupdate policy

Dimmer testDim "dimmer [%s]" {channel="modbus:data:dummy:dummy_h20:dimmer"}
2020-06-28 01:37:51.962 [ome.event.ItemCommandEvent] - Item 'testDim' received command 75
2020-06-28 01:37:52.061 [nt.ItemStatePredictedEvent] - testDim predicted to become 75
2020-06-28 01:37:52.092 [vent.ItemStateChangedEvent] - testDim changed from 100 to 75

Here we can see –

  • Where there is a channel link, autoupdate logs a prediction
  • That prediction is applied to the Item immediately
  • If the binding later produces an update, it should be to the same value usually, and so will not be seen in the log.

Note that the above refers to Items linked to channels.
If your Item is linked only to a v1.x binding, like so

Dimmer testDim "dimmer [%s]" {udp=">[*:10.10.1.21:1001:default]}
2020-06-28 01:54:17.826 [ome.event.ItemCommandEvent] - Item 'testDim' received command 50
2020-06-28 01:54:17.842 [vent.ItemStateChangedEvent] - testDim changed from 75 to 50

We see it will behave like an unlinked Item, i.e.

  • there will be no prediction logged
  • but the update will be carried out.

Linked Item with broken channel or an OFFLINE Thing, or binding veto

Dimmer testDim "dimmer [%s]" {channel="rubbish:garbage:junk:broken"}
2020-06-28 02:00:50.553 [ome.event.ItemCommandEvent] - Item 'testDim' received command 25
2020-06-28 02:00:50.570 [nt.ItemStatePredictedEvent] - testDim predicted to become 50

Here we see something perhaps unexpected.

  • The openHAB framework interprets a broken channel as implying “this command cannot work”, and effectively vetoes autoupdate.
  • A prediction is however offered – that the state will remain the same as before the (failed) command.
    That might seem a bit odd – but remember a UI can listen for prediction events, and so indicate to the user that an expected change didn’t happen, e.g. a slider that pings back when released.
  • Obviously, no state change event takes place.

Linked Item with broken channel, but forcing autoupdate

Dimmer testDim "dimmer [%s]" {channel="rubbish:garbage:junk:broken", autoupdate="true"}
2020-06-28 02:17:03.346 [ome.event.ItemCommandEvent] - Item 'testDim' received command 35
2020-06-28 02:17:03.366 [vent.ItemStateChangedEvent] - testDim changed from 50 to 35

Here we see the effect of forcing autoupdate over a veto -

  • a prediction is not logged, but is made and applied
  • this is different to just leaving autoupdate as default for this Item
8 Likes

this is excellent - I’ve been using openhab for six years, but never properly understood autoupdate