Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hdpowerview] Update positions after triggering scene/scene group #11768

Conversation

jlaur
Copy link
Contributor

@jlaur jlaur commented Dec 12, 2021

When triggering a scene or scene group, some shades will have new positions. These new positions are available in the hub immediately after triggering the scene or scene group, i.e. before the shades will reach those new positions.

Previously it would take up to one minute to have the positions refreshed. Now it will happen a few seconds after the scene or scene group has been triggered.

Fixes #11697

Signed-off-by: Jacob Laursen [email protected]

Test documentation

Before change:

2021-12-12 21:26:42.228 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'PowerViewHub_Scene_Office_Up' received command ON
2021-12-12 21:27:08.782 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Blind9_Position' changed from 100 to 0

After change:

2021-12-12 21:50:22.834 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'PowerViewHub_Scene_Office_Up' received command ON
2021-12-12 21:50:26.105 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Blind9_Position' changed from 100 to 0

And back:

2021-12-12 21:50:29.706 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'PowerViewHub_Scene_Office_Down' received command ON
2021-12-12 21:50:32.955 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Blind9_Position' changed from 0 to 100

@jlaur
Copy link
Contributor Author

jlaur commented Dec 12, 2021

FYI @andrewfg, @arroyoj

@andrewfg
Copy link
Contributor

I think equals() and == compile to the same thing. ??

@andrewfg
Copy link
Contributor

Also wondering if you should replace the pollshades() calls with scheduler.submit([ -> | pollshades()]) ??

@jlaur
Copy link
Contributor Author

jlaur commented Dec 12, 2021

I think equals() and == compile to the same thing. ??

See https://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals

So it's faster and safer at compile-time as well as runtime.

@jlaur jlaur closed this Dec 12, 2021
@jlaur jlaur reopened this Dec 12, 2021
@jlaur
Copy link
Contributor Author

jlaur commented Dec 12, 2021

Also wondering if you should replace the pollshades() calls with scheduler.submit([ -> | pollshades()]) ??

Done.

@arroyoj
Copy link

arroyoj commented Dec 13, 2021

@jlaur, thanks for putting this together. It all looks good to me. Do you have a JAR available so that I can try using it?

@jlaur
Copy link
Contributor Author

jlaur commented Dec 13, 2021

@arroyoj
Copy link

arroyoj commented Dec 14, 2021

@jlaur, thanks for sharing the JAR. I tested it out on my machine, and it worked great. Similar to your testing, I saw that the shade positions got updated in ~4 seconds after triggering a scene, rather than up to 1 min like before. I didn't see any issues. Thanks again for this fix.

@jlaur jlaur marked this pull request as draft December 19, 2021 11:29
@jlaur jlaur marked this pull request as ready for review December 19, 2021 11:42
@jlaur
Copy link
Contributor Author

jlaur commented Dec 19, 2021

Also wondering if you should replace the pollshades() calls with scheduler.submit([ -> | pollshades()]) ??

@andrewfg - please see thread from @lolodomo's comment. Decided to revert and go back to synchronous HTTP call for simplicity. Only difference is that we have two sync calls where previously we had one. With the previous changes we would have one sync and one async, and it became messy.

@andrewfg
Copy link
Contributor

Decided to revert and go back to synchronous HTTP call for simplicity.

I don’t agree. I am not so much concerned about an extra HTTP call. What concerns me is that you are making re-entrant calls to the OH core; whilst you are still within handleCommand() for one channel, you run pollShades which makes multiple updateChannel callbacks to the core; in fact one call back from each channel and each shade in your system. So your handleCommand could potentially cause the OH core to block on itself. Not good.

@jlaur jlaur marked this pull request as draft December 19, 2021 12:14
@jlaur
Copy link
Contributor Author

jlaur commented Dec 19, 2021

Decided to revert and go back to synchronous HTTP call for simplicity.

I don’t agree. I am not so much concerned about an extra HTTP call. What concerns me is that you are making re-entrant calls to the OH core; whilst you are still within handleCommand() for one channel, you run pollShades which makes multiple updateChannel callbacks to the core; in fact one call back from each channel and each shade in your system. So your handleCommand could potentially cause the OH core to block on itself. Not good.

Ahh - thanks for this explanation. New approach needed, marking PR as draft.

@andrewfg
Copy link
Contributor

Perhaps your prior attempt was overkill; I understand why you had to wrap the asynch pollShades call in an exception handler, but perhaps it is easier to let the existing code do the heavy lifting rather than reinventing the wheel; so after handleCommand triggered the scene, you could just 'submit' a call to poll() as follows..

scheduler.submit(() -> {
    poll();
});

@jlaur
Copy link
Contributor Author

jlaur commented Dec 19, 2021

Perhaps your prior attempt was overkill; I understand why you had to wrap the asynch pollShades call in an exception handler, but perhaps it is easier to let the existing code do the heavy lifting rather than reinventing the wheel; so after handleCommand triggered the scene, you could just 'submit' a call to poll() as follows..

scheduler.submit(() -> {
    poll();
});

poll will perform four calls in total:

  • fetch shades
  • fetch scenes
  • fetch scene collections
  • fetch scheduled events

and we need only one of them. Still, it would be much simpler like you described, so could be refactored into something like that. My concern is that if we schedule a fire-and-forget call like that, we might have a problem in case dispose() is called right after while operation is still ongoing in future, for which we don't have a hook for cancelling it?

@jlaur
Copy link
Contributor Author

jlaur commented Dec 19, 2021

My concern is that if we schedule a fire-and-forget call like that, we might have a problem in case dispose() is called right after while operation is still ongoing in future, for which we don't have a hook for cancelling it?

Perhaps we could reschedule existing future as a compromise? We would still fetch everything, but at least we would postpone next ordinary poll for another minute:

    private void rescheduleSoftPoll() {
        ScheduledFuture<?> future = this.pollFuture;
        if (future != null) {
            future.cancel(false);
        }
        logger.debug("Rescheduling poll every {}ms", refreshInterval);
        this.pollFuture = scheduler.scheduleWithFixedDelay(this::poll, 0, refreshInterval, TimeUnit.MILLISECONDS);
    }

And we would have the future cancelled from dispose.

@andrewfg
Copy link
Contributor

I think there is no need to worry about that: firstly the sheduler is part of the core, so if the core is shutting down, it will do so cleanly (it won't start un-run tasks, and it won't interrupt already running ones); and secondly the poll method is marked as synchronized so it cannot be called in parrallel.

Obviously if you unpack the poll() method, you will need to think carefully about placing the synchronized marker on any of its parts, since you would be introducing a risk of self blocking between regular polls and this special poll.

In summary I would still just submit poll; who cares if its updating other channels? It is essentially just doing another regular poll a bit earlier than the normal polling cycle would do so..

@andrewfg
Copy link
Contributor

Perhaps we could reschedule existing future

Yes, that would work.

Signed-off-by: Jacob Laursen <[email protected]>
@jlaur
Copy link
Contributor Author

jlaur commented Dec 19, 2021

Perhaps we could reschedule existing future

Yes, that would work.

Done.

@jlaur jlaur marked this pull request as ready for review December 19, 2021 14:24
Copy link
Contributor

@andrewfg andrewfg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines 133 to 144
int id = Integer.parseInt(channelUID.getIdWithoutGroup());
if (sceneChannelTypeUID.equals(channel.getChannelTypeUID()) && OnOffType.ON.equals(command)) {
if (sceneChannelTypeUID.equals(channel.getChannelTypeUID()) && OnOffType.ON == command) {
webTargets.activateScene(id);
} else if (sceneGroupChannelTypeUID.equals(channel.getChannelTypeUID()) && OnOffType.ON.equals(command)) {
// Reschedule soft poll for immediate shade position update.
scheduleSoftPoll(0);
} else if (sceneGroupChannelTypeUID.equals(channel.getChannelTypeUID()) && OnOffType.ON == command) {
webTargets.activateSceneCollection(id);
// Reschedule soft poll for immediate shade position update.
scheduleSoftPoll(0);
} else if (automationChannelTypeUID.equals(channel.getChannelTypeUID())) {
webTargets.enableScheduledEvent(id, OnOffType.ON.equals(command));
webTargets.enableScheduledEvent(id, OnOffType.ON == command);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@lolodomo lolodomo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lolodomo lolodomo merged commit 817de38 into openhab:main Dec 20, 2021
@lolodomo lolodomo added this to the 3.3 milestone Dec 20, 2021
@lolodomo lolodomo added the enhancement An enhancement or new feature for an existing add-on label Dec 20, 2021
@andrewfg
Copy link
Contributor

@lolodomo thanks for reviewing and merging the HDPowerView PR's of @jlaur (which I had approved); but could you please also review my own PR #11698 so that we can keep things in sync?

@lolodomo
Copy link
Contributor

@lolodomo thanks for reviewing and merging the HDPowerView PR's of @jlaur (which I had approved); but could you please also review my own PR #11698 so that we can keep things in sync?

Really big one. Probably too much to expect a fast review from myself

mherwege pushed a commit to mherwege/openhab-addons that referenced this pull request Dec 23, 2021
…enhab#11768)

* Update positions after triggering scene/scene group.
* Compare enum values directly with ==
* Fix re-entrant calls.

Fixes openhab#11697

Signed-off-by: Jacob Laursen <[email protected]>
NickWaterton pushed a commit to NickWaterton/openhab-addons that referenced this pull request Dec 30, 2021
…enhab#11768)

* Update positions after triggering scene/scene group.
* Compare enum values directly with ==
* Fix re-entrant calls.

Fixes openhab#11697

Signed-off-by: Jacob Laursen <[email protected]>
Signed-off-by: Nick Waterton <[email protected]>
mischmidt83 pushed a commit to mischmidt83/openhab-addons that referenced this pull request Jan 9, 2022
…enhab#11768)

* Update positions after triggering scene/scene group.
* Compare enum values directly with ==
* Fix re-entrant calls.

Fixes openhab#11697

Signed-off-by: Jacob Laursen <[email protected]>
Signed-off-by: Michael Schmidt <[email protected]>
nemerdaud pushed a commit to nemerdaud/openhab-addons that referenced this pull request Jan 28, 2022
…enhab#11768)

* Update positions after triggering scene/scene group.
* Compare enum values directly with ==
* Fix re-entrant calls.

Fixes openhab#11697

Signed-off-by: Jacob Laursen <[email protected]>
andan67 pushed a commit to andan67/openhab-addons that referenced this pull request Nov 6, 2022
…enhab#11768)

* Update positions after triggering scene/scene group.
* Compare enum values directly with ==
* Fix re-entrant calls.

Fixes openhab#11697

Signed-off-by: Jacob Laursen <[email protected]>
andrasU pushed a commit to andrasU/openhab-addons that referenced this pull request Nov 12, 2022
…enhab#11768)

* Update positions after triggering scene/scene group.
* Compare enum values directly with ==
* Fix re-entrant calls.

Fixes openhab#11697

Signed-off-by: Jacob Laursen <[email protected]>
Signed-off-by: Andras Uhrin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An enhancement or new feature for an existing add-on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[hdpowerview] Update position Channels immediately when a Scene (Collection) is triggered.
4 participants