New PJLink Binding for controlling multiple projector brands/models

Hi everyone,

I’ve implemented a PJLink binding for openHAB.

It allows to control devices which implement the standard, in particular digital projectors. The binding currently supports PJLink class 1 including authentication.

A lot of well known projector manufacturers are involved in the standard, e.g. Sony, Panasonic, NEC, and many more. Even if it is not officially mentioned, also Acer projectors support the standard (at least some, like mine).

The binding is available in OpenHAB 2.5.x and 3.x.

Feel free to try it with your projector and let me know if you run into issues!

Best Regards,
Nils

3 Likes

Hi,

How i Can install this binding?
I don´t can find the .jar install data, or i must be create the .jar self ?

I have been searching for this binding for a long time.:slightly_smiling_face:

Best Regards,
itsego

Hi itseogo,

you can find the most recent jar from the pull request here:
https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/binding/org.openhab.binding.pjlinkdevice/2.5.0-SNAPSHOT/

I’m pretty sure you’ll have to use an openHAB 2.4.0 milestone/development build, as the binding makes use of some more recent API.

Best Regards,
Nils

Hi,

i can´t use the binding, i have Error when i will install.

ecuting command: Error installing bundles:
Unable to install bundle 269: org.osgi.framework.BundleException: Error reading bundle content.

and when i will start the binding get this Error.

Error executing command: Error executing command on bundles:
Error starting bundle 269: Could not resolve module: org.openhab.binding.pjlinkdevice [269]
Unresolved requirement: Import-Package: gnu.io; resolution:="optional"
Unresolved requirement: Import-Package: org.eclipse.jdt.annotation; resolution:="optional"
Unresolved requirement: Import-Package: org.eclipse.smarthome.config.discovery.upnp

I use Openhab 2.0.4.M5 on Raspiberry Pi.

Have you a idea what i can to do ?

Hi itseogo,

thanks for testing! The JAR has been updated, could you please try again?

Best Regards,
Nils

Edit: Removed outdated 2.4.0-SNAPSHOT link to avoid confusion.

Hi,

Thanks ,now it works the binding update,
I have test the binding with a EPSON EB-4750W (PJ link Class 1) and EPSON EB-5530U (PJ link Class 2) it works.
I can Power off/on and change the Inputs.

I tried the add-on with my Optoma UHD60 is supports PJLink and the feature is turned on.

First issue I had was that the auto discovery didn’t seem te work. No problem i added a optoma.thing file with the correct IP address.

Then the logger gives me:

==> /var/log/openhab2/events.log <==
2018-12-30 16:27:07.156 [hingStatusInfoChangedEvent] - 'pjLinkDevice:pjLinkDevice:MyProjector' changed from UNINITIALIZED to INITIALIZING
2018-12-30 16:27:07.671 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.719 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.733 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.742 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.768 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.779 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.801 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.809 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.815 [me.event.ThingUpdatedEvent] - Thing 'pjLinkDevice:pjLinkDevice:MyProjector' has been updated.
2018-12-30 16:27:07.824 [hingStatusInfoChangedEvent] - 'pjLinkDevice:pjLinkDevice:MyProjector' changed from INITIALIZING to OFFLINE (COMMUNICATION_ERROR): Expected prefix {0}, instead got {1}
==> /var/log/openhab2/openhab.log <==
2018-12-30 16:27:08.871 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'optoma.things'

I tried https://github.com/multiOTP/pjlink/blob/master/pjlink.class.php this script just to be sure it wasn’t an error on the side of the beamer. This works fine (power on / off).

Hi struvusmaximus,

I have config this binding over the Paper UI, i don´t know to can use auto discovery in this binding.

.

have you write the port in the optoma.thing?

I had a white screen in paper UI when clicking "Inbox > PJLinkDevice Binding " after installing the binding.
I just tried again and now I can add the thing through paper UI (must be some kind of caching issue with paper ui).

But the error stays the same.

oh okay, you can try with the PJ link tool to simulate a other PJlink device.

https://pjlink.jbmia.or.jp/english/data/5-2_test_cd.zip



have you try a reboot after the binding install ?
What for a openhab version it use ?

I rebooted openhab (I use 2.4.0 release) didn’t work.

Then I used your test program and it found the thing successfully and is online.

I then removed the manual made optoma thing file and tried again by adding it through Paper UI.
This still doesn’t work. It seems some info comes in (disclosedname)


But not all.

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 ?