New PJLink Binding for controlling multiple projector brands/models

Tags: #<Tag:0x00007f386edbd2d0> #<Tag:0x00007f386edbd168> #<Tag:0x00007f386edbd028>

okay, you can try to connect over optoma.thing to you projector.

what kind of system is openhab running on? Raspi?Linux?Windows?
maybe the binding have not enough rights for the paper ui ?

my rights on this binding on my raspi:
image

I checked and changed the rights temporarily to 777 but this doesn’t help.
My system is openHAB on a RPI3.

It seems like the optoma is sending some responses in a different format as in it doesn’t startsWith(fullPrefix)
Maybe you can build in some logging so I can check what responses actually come in? I already set the loglevel to debug for this binding.

public void parse(String response) throws ResponseException {
	        String fullPrefix = "%1" + this.prefix;
	        if (!response.startsWith(fullPrefix)) {
	            throw new ResponseException(
	                    MessageFormat.format("Expected prefix '{0}', instead got '{1}'", fullPrefix, response));
	        }

Hi Mark and itseogo,

thanks for testing the binding and analyzing the issue with the Optoma Projector.

I was thinking the same thing concerning the logging message, as you can see from the code it was intended to be more meaningful… I can’t fix that right now, but in the afternoon I will create a new version.

Maybe the Optoma responds with a class 2 response when we send class 1 commands or something like that.

I’ll let you know when the new JAR is available.

Best Regards,
Nils

1 Like

Hi Mark,

the snapshot JAR has been updated. Caution: the JAR has a new URL as it is now a 2.5.0-SNAPSHOT instead of 2.4.0-SNAPSHOT after OpenHAB 2.4.0 has been released.

When you set the log level of org.openhab.binding.pjlinkdevice to at least INFO, you should now see log messages like these:

Got response '%1POWR=OK' for request '%1POWR 0\r' from /192.168.178.120

Also, the exception now is working with a proper text, e.g.:

Expected prefix '%1INFO=', instead got '%2INFO=Projector-Other'

tried the new snapshot and the log states:

2019-01-01 14:41:01.139 [hingStatusInfoChangedEvent] - 'pjLinkDevice:pjLinkDevice:ac61ae92' changed from UNINITIALIZED (HANDLER_MISSING_ERROR) to INITIALIZING
2019-01-01 14:41:01.148 [INFO ] [kdevice.internal.device.PJLinkDevice] - Authentication not needed
2019-01-01 14:41:01.159 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1NAME=Optoma UHD' for request '%1NAME ?\r' from /192.168.1.61
2019-01-01 14:41:01.162 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '' for request '%1INF1 ?\r' from /192.168.1.61
2019-01-01 14:41:01.173 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1INF1=Optoma' for request '%1INF2 ?\r' from /192.168.1.61
2019-01-01 14:41:01.180 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1INF2=Optoma UHD' for request '%1INF1 ?\r' from /192.168.1.61
2019-01-01 14:41:01.186 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1INF1=Optoma' for request '%1INF2 ?\r' from /192.168.1.61
2019-01-01 14:41:01.193 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1INF2=Optoma UHD' for request '%1NAME ?\r' from /192.168.1.61
2019-01-01 14:41:01.200 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1NAME=Optoma UHD' for request '%1CLSS ?\r' from /192.168.1.61
2019-01-01 14:41:01.203 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '' for request '%1ERST ?\r' from /192.168.1.61
2019-01-01 14:41:01.206 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1CLSS=Class 1' for request '%1LAMP ?\r' from /192.168.1.61
2019-01-01 14:41:01.211 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1ERST=000000' for request '%1INFO ?\r' from /192.168.1.61
2019-01-01 14:41:01.217 [INFO ] [kdevice.internal.device.PJLinkDevice] - Got response '%1LAMP=152 0' for request '%1INST ?\r' from /192.168.1.61
2019-01-01 14:41:01.224 [hingStatusInfoChangedEvent] - 'pjLinkDevice:pjLinkDevice:ac61ae92' changed from INITIALIZING to OFFLINE (COMMUNICATION_ERROR): Expected prefix '%1INST=', instead got '%1LAMP=152 0'

Okay, this looks a bit like the binding is not patient enough to wait for the response from the projector.

I’ll have a look at the PJLink specs again to see whether that’s something that can be expected.
Regardless of the outcome of that, I’ll also provide a new version which is hopefully more robust in that regard soon.

Best Regards,
Nils

1 Like

Hello again,

further thinking about it, it rather seems that there are sometimes unexpected empty lines coming from the projector. The most recent JAR should now ignore empty lines and try to get another one.

@itseogo @struvusmaximus Could you please both test it with your projectors again? The binding works fine with the PJLink test tool, but unfortunately I can not do a regression test with my real projector at the moment.

Best Regards,
Nils

Hello Nils,

it works like a charm!
Thanks for the quick fix. I would say this addon can be merged in Git.
I added my comment/feedback there also.

1 Like

@nils.schnabel

can you provide detailed instructions to install the jar file ?

I’ve figured out: I put the jar file inside the “addons” directory and restart openhab

After a while, it became available in the inbox “+” section.

I’ve provided the IP and the port that is displayed in the web UI of the projector (type the IP of the project, port 80, go to setup, default login/password is root/Projector), and go to PJTalk.

With this port I get the following error:

2019-01-04 00:01:43.891 [WARN ] [core.thing.internal.ThingManagerImpl] - Initializing handler for thing 'pjLinkDevice:pjLinkDevice:2f8feae4' takes more than 5000ms.
2019-01-04 00:02:08.970 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHandler.initialize()' on 'org.openhab.binding.pjlinkdevice.internal.PJLinkDeviceHandler@7b3531a4': null
java.lang.NullPointerException: null
	at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:123) ~[?:?]
	at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:91) ~[?:?]
	at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.checkAvailability(PJLinkDevice.java:205) ~[?:?]
	at org.openhab.binding.pjlinkdevice.internal.PJLinkDeviceHandler.initialize(PJLinkDeviceHandler.java:145) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [102:org.eclipse.smarthome.core:0.10.0.oh240]
	at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:53) [102:org.eclipse.smarthome.core:0.10.0.oh240]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
	at java.lang.Thread.run(Thread.java:748) [?:?]
2019-01-04 00:02:08.999 [ERROR] [core.thing.internal.ThingManagerImpl] - Exception occurred while initializing handler of thing 'pjLinkDevice:pjLinkDevice:2f8feae4': null
java.lang.NullPointerException: null
	at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:123) ~[?:?]
	at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:91) ~[?:?]
	at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.checkAvailability(PJLinkDevice.java:205) ~[?:?]
	at org.openhab.binding.pjlinkdevice.internal.PJLinkDeviceHandler.initialize(PJLinkDeviceHandler.java:145) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:153) [102:org.eclipse.smarthome.core:0.10.0.oh240]
	at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:53) [102:org.eclipse.smarthome.core:0.10.0.oh240]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
	at java.lang.Thread.run(Thread.java:748) [?:?]

with the default port, I get a “connection refused”.

Any ideas ?

Hi Thomas,

I’ve looked up PJLink and PJ Talk and it seems that despite the similar name, those protocols work differently on a technical level.

I also looked up your projector (Sony VPL-HW65, right?) on the PJLink supported devices pages, but it was not mentioned there. As many other Sony projectors are listed, I assume that your projector does not support PJLink (but PJ Talk, but this binding here is only for PJLink).

Thanks for testing regardless :+1: , because your results give me an opportunity to improve the exception handling in this binding. Something more meaningful than a NPE would be nice, right? :slight_smile:

Best Regards,
Nils

Any idea if it would be possible to support PJTalk? just power on / power off would be enough.

Do you have a link about the PJTalk protocol ? I’ll have a look.

I don’t think it makes sense to have PJ Talk in this PJLink binding, because

  • the protocols are different on a technical level
  • PJLink is a cross-vendor standard, PJ Talk seems to be Sony specific

So for PJ Talk there needs to be a separate binding, I think you should continue to follow the developments at GitHub issue #4354.

One piece of documentation I found concerning PJ Talk is this PDF.
This is enough information for me to see that it’s a protocol technically unrelated to PJLink.

Thanks I’ll try the other plugin

@nils.schnabel the plugin is still working fine but I have a question/request.
Would it be possible to get the power status of the beamer?

The use case is that when I enable the beamer scene (beamer on, screen down etc) with openhab app the power status is known. And a rule which uses a sensor to turn on the light isn’t triggered.

But sometimes our household turns on the beamer with the remote and the scene isn’t working properly because the status of the beamer is not updated in Openhab.

Hi Mark,

technically it would be feasible to support that in those ways:

  1. PJLink Class 2 has a Status Notification Protocol in place, which can be used by the projector to inform subscribers about status changes.
  2. Interval polling could be used to frequently request the current status of the projector

Right now, I have some blockers for both of them:

  1. Currently the binding only supports Class 1, for the simple reason that I do not own a Class 2 device myself. I could develop support for Class 2 features and test it with the JBMIA test tool, but I would only do so if there is a chance that the binding is ever being merged. I won’t invest that much more effort as long as it is unclear whether the binding can be accepted. Also, this approach would not work with Class 1 devices, so alternative #2 seems more appropriate to start with.

  2. Seems rather simple to do technically, but I’d prefer to do it the ‘OpenHAB way’. I’m pretty sure there are some best practices for OpenHAB bindings how to do that, but I could not find any example or documentation.

So if someone more experienced with OH binding development could help me by giving me some hints how to do polling properly, I’d be happy to start with the development of alternative #2. Edit: I’ve asked for help in the development community (Binding Development: Best Practices for Polling)

Best Regards,
Nils

@struvusmaximus Sadly it turned out a bit more complicated than expected…

With the PJLink test tool I got it working quickly, but my real projector has its special behaviours. It does not like polling on the selected input at all (blocks the request until a timeout occurs), so I created three additional configuration options to enable/disable polling of power, mute, input channel respectively.

The binding is currently building and should be available in max. 2 hours from now at the usual URL.

Best Regards,
Nils

thanks @nils I just tested the new snapshot with two beamers and the new status polling works fine!

I also see your binding got some feedback from the maintainers. So hopefully your work will be added to the add-on repo in the near future.
Thanks for all the effort you already put in this binding.

1 Like

Hi all,

Just want to confirm this binding is also working fine with my Epson EH-TW9400 projector (also known as Pro Cinema 6050UB), which is a PJ link class 2

Thanks for the development!

1 Like

Hi
I try to use this Binding with a Optoma UHD3700. But I got only a Communication Error Read timed out.
When I used the Testprogram mentioned befor its working.

I use the last binding 2.5 with the latest Openhabian on an Respberry Pi

Hi Matthias,

please set the log level of org.openhab.binding.pjlinkdevice to at least INFO and add your projector again. Then post the corresponding log file section here, maybe I can identify the issue this way.