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

[epsonprojector] Update epsonprojector binding for OH3 #9021

Merged
merged 17 commits into from
Dec 4, 2020

Conversation

mlobstein
Copy link
Contributor

@mlobstein mlobstein commented Nov 14, 2020

I have picked up where PR #7370 left off to bring the epsonprojector binding back for OH3. I have finished cleaning up the code & documentation and tested with two older projectors. Thanks to @ghys for starting this effort.

Test build:
https://github.com/mlobstein/mlobstein-beta-test/raw/master/org.openhab.binding.epsonprojector-3.0.0-SNAPSHOT.jar

https://github.com/mlobstein/mlobstein-beta-test/raw/master/org.openhab.binding.epsonprojector-3.0.0-SNAPSHOT-sources.jar

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
@ghys
Copy link
Member

ghys commented Nov 14, 2020

And thanks to you for finishing it @mlobstein! - it looks good and will surely be better maintained by you :) The implementation wasn't perfect, mostly straight from OH1, querying for unavailable data when off etc. But I had some stability issues when the connection was closed too frequently, after some time the projector wouldn't respond to any commands so I figure I didn't want to mess with it too much once it was stable enough for me. Nonetheless, glad to see that improved! I'll be sure to give it a try asap.

@cpmeister cpmeister added new binding If someone has started to work on a binding. For a new binding PR. oh1 migration Relates to migrating an openHAB 1 addon to openHAB 2 labels Nov 16, 2020
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
@fwolter fwolter self-assigned this Nov 20, 2020
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
@ghys
Copy link
Member

ghys commented Nov 22, 2020 via email

@fwolter
Copy link
Member

fwolter commented Nov 22, 2020

It was only a suggestion. I'm fine if you keep all three authors.

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Copy link
Member

@fwolter fwolter left a comment

Choose a reason for hiding this comment

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

LGTM

@fwolter fwolter added the cre Coordinated Review Effort label Nov 24, 2020
@fwolter fwolter removed their assignment Nov 24, 2020
Comment on lines 114 to 122
pollingJob = scheduler.scheduleWithFixedDelay(() -> {
for (Channel channel : channels) {
// only query power & lamp time when projector is off
if (isPowerOn || (channel.getUID().getId().equals(CHANNEL_TYPE_POWER)
|| channel.getUID().getId().equals(CHANNEL_TYPE_LAMPTIME))) {
updateChannelState(channel);
}
}
}, 0, (pollingInterval > 0) ? pollingInterval : DEFAULT_POLLING_INTERVAL_SEC, TimeUnit.SECONDS);
Copy link
Contributor

@cpmeister cpmeister Nov 25, 2020

Choose a reason for hiding this comment

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

You should avoid assigning class fields asynchronously since this handler might get disposed before you have a chance to assign it. This might lead to the case where this periodic task is never canceled.

Instead you should create this task during initialize and then inside the task just check if the device is connected or not before trying to update the channels.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be fixed now.

Comment on lines +75 to +77
if (in.markSupported()) {
in.reset();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

At no point to you create any marks. What exactly are you resetting here?

Copy link
Contributor Author

@mlobstein mlobstein Nov 26, 2020

Choose a reason for hiding this comment

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

I don't know. All the communication code is unchanged for the most part from #7370 and #6922.

Comment on lines +41 to +42
private @Nullable InputStream in = null;
private @Nullable OutputStream out = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

You only seem to write characters to these streams. Why not make these a Reader and Writer instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had not considered this since the code was already written and had been scrutinized by the above mentioned PRs.

Comment on lines +46 to +47
private @Nullable InputStream in = null;
private @Nullable OutputStream out = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

same suggestion

public void serialEvent(SerialPortEvent arg0) {
}

private String sendMmsg(String data, int timeout) throws IOException, EpsonProjectorException {
Copy link
Contributor

Choose a reason for hiding this comment

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

How are you handling the case where multiple message are sent at the same time from multiple threads? Are you already preventing this from happening?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is called by sendQuery() which is a synchronized method... Is that sufficient?

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks sufficient, but it would be safer if you did the synchronization in this class instead. It looks safe enough as is though, so you don't have to change it.

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Comment on lines 76 to 80
if (THING_TYPE_PROJECTOR_SERIAL.equals(thingTypeUID)) {
device = new EpsonProjectorDevice(serialPortManager, getConfigAs(EpsonProjectorConfiguration.class));
} else {
device = new EpsonProjectorDevice(getConfigAs(EpsonProjectorConfiguration.class));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

You should move this to initialize() method, otherwise user configuration changes are not taken in use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, but then device still needs to be set to something here to satisfy the notnullbydefault. And EpsonProjectorDevice needs a connector in the constructor which is why I had done the EpsonProjectorDefaultConnector.

Copy link
Contributor

@paulianttila paulianttila Nov 26, 2020

Choose a reason for hiding this comment

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

Well, notnullbydefault just forces you to think which field can be null and which not. In this case device can't be initialised or be final as it depends on the thing configuration an it can change during thing life time.

So it should be fine to be nullable

private @Nullable EpsonProjectorDevice device;

or if you want to avoid nulls, you could make it optional

private Optional<EpsonProjectorDevice> device = Optional.empty();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, fixed (using Optional).

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
public void serialEvent(SerialPortEvent arg0) {
}

private String sendMmsg(String data, int timeout) throws IOException, EpsonProjectorException {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks sufficient, but it would be safer if you did the synchronization in this class instead. It looks safe enough as is though, so you don't have to change it.

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Comment on lines 131 to 133
scheduler.scheduleWithFixedDelay(() -> {
ready = true;
}, 0, 10000, TimeUnit.MILLISECONDS);
Copy link
Contributor

Choose a reason for hiding this comment

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

You need to keep track of the Future this returns so you can cancel it during disconnect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this was put in to get rid of a 10 second thread.sleep(). It should only be a one time delay for 10 seconds before setting ready back to true, so I changed it to schedule() instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

You still need to track the future so you can cancel it if the handler is disposed before 10 seconds expires.

Copy link
Member

Choose a reason for hiding this comment

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

I think there's a glitch in the Matrix #9021 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made it cancel on disconnect.

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Copy link
Contributor

@cpmeister cpmeister left a comment

Choose a reason for hiding this comment

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

Just some minor final tweaks.


private void updateChannelState(Channel channel) {
try {
if (!isLinked(channel.getUID()) && !channel.getUID().getId().equals(CHANNEL_TYPE_POWER)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

power state will be queried even if the channel isn't linked?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes for two reasons:

  1. If no channels are linked, power is still checked as a ping of the device to set the status to ONLINE and later OFFLINE if the connection is lost.
  2. In the edge case of the user not linking the power channel, the power status still needs to be known to properly set the isPowerOn boolean (ie: only PWR? and LAMP? queries can be done when the power is off, because all others would fail).

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
@cpmeister cpmeister added rebuild Triggers Jenkins PR build and removed rebuild Triggers Jenkins PR build labels Dec 1, 2020
@cpmeister cpmeister merged commit ffe252c into openhab:main Dec 4, 2020
@cpmeister cpmeister added this to the 3.0.0.M5 milestone Dec 4, 2020
@mlobstein mlobstein deleted the Epson_OH3 branch December 12, 2020 04:41
nowaterman pushed a commit to nowaterman/openhab-addons that referenced this pull request Jan 19, 2021
* baseline EpsonProjector code from ysc
* Improvements for OH3
* Finish epsonprojector binding for OH3
* improve exception logging
* cleanup exception logging
* Make connection specific thing types
boehan pushed a commit to boehan/openhab-addons that referenced this pull request Apr 12, 2021
* baseline EpsonProjector code from ysc
* Improvements for OH3
* Finish epsonprojector binding for OH3
* improve exception logging
* cleanup exception logging
* Make connection specific thing types

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
marcfischerboschio pushed a commit to bosch-io/openhab-addons that referenced this pull request May 5, 2022
* baseline EpsonProjector code from ysc
* Improvements for OH3
* Finish epsonprojector binding for OH3
* improve exception logging
* cleanup exception logging
* Make connection specific thing types

Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cre Coordinated Review Effort new binding If someone has started to work on a binding. For a new binding PR. oh1 migration Relates to migrating an openHAB 1 addon to openHAB 2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants