New PJLink Binding for controlling multiple projector brands/models

Tags: #<Tag:0x00007faecbf139a8> #<Tag:0x00007faecbf13868> #<Tag:0x00007faecbf13728>

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.

Hi at the Scan for the address I got this Log Entry
2019-06-16 14:41:41.605 [WARN ] [discovery.DiscoveryParticipantClass1] - No PJLinkDevice here /192.168.1.153 [java.net.PlainSocketImpl.socketConnect(Native Method), java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350), java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206), java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188), java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392), java.net.Socket.connect(Socket.java:589), org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:117), org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:88), org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.checkAvailability(PJLinkDevice.java:206), org.openhab.binding.pjlinkdevice.internal.discovery.DiscoveryParticipantClass1.checkAddress(DiscoveryParticipantClass1.java:77), org.openhab.binding.pjlinkdevice.internal.discovery.AbstractDiscoveryParticipant.lambda$0(AbstractDiscoveryParticipant.java:56), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624), java.lang.Thread.run(Thread.java:748)]

If it try to add the Projector manualy I see in the log this entry

2019-06-16 14:44:02.718 [hingStatusInfoChangedEvent] - ‘pjLinkDevice:pjLinkDevice:e19d51a1’ changed from UNINITIALIZED to INITIALIZING

==> /var/log/openhab2/openhab.log <==

2019-06-16 14:44:03.159 [WARN ] [kdevice.internal.device.PJLinkDevice] - Cannot handle introduction response pjlink 0

2019-06-16 14:44:03.166 [WARN ] [kdevice.internal.device.PJLinkDevice] - Could not create a socket connection

org.openhab.binding.pjlinkdevice.internal.device.command.ResponseException: Invalid header: pjlink 0

at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:149) [269:org.openhab.binding.pjlinkdevice:2.5.0.201903011503]

at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.connect(PJLinkDevice.java:88) [269:org.openhab.binding.pjlinkdevice:2.5.0.201903011503]

at org.openhab.binding.pjlinkdevice.internal.device.PJLinkDevice.checkAvailability(PJLinkDevice.java:206) [269:org.openhab.binding.pjlinkdevice:2.5.0.201903011503]

at org.openhab.binding.pjlinkdevice.internal.PJLinkDeviceHandler.setupDevice(PJLinkDeviceHandler.java:201) [269:org.openhab.binding.pjlinkdevice:2.5.0.201903011503]

at org.openhab.binding.pjlinkdevice.internal.PJLinkDeviceHandler.initialize(PJLinkDeviceHandler.java:182) [269:org.openhab.binding.pjlinkdevice:2.5.0.201903011503]

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) [?:?]

==> /var/log/openhab2/events.log <==

2019-06-16 14:44:03.241 [hingStatusInfoChangedEvent] - ‘pjLinkDevice:pjLinkDevice:e19d51a1’ changed from INITIALIZING to OFFLINE (COMMUNICATION_ERROR): Invalid header: pjlink 0

If I use the Test Programm it works well and I got the follow responce

[2019.06.16 14:46:41.320] Connected!!!
[2019.06.16 14:46:41.595] RECV:pjlink 0

[2019.06.16 14:46:41.604] SEND:%1LAMP ?

[2019.06.16 14:46:41.764] RECV:%1lamp=4 1

[2019.06.16 14:46:41.771] Closed!!!(Disconnect)
[2019.06.16 14:46:45.049] Connected!!!
[2019.06.16 14:46:45.300] RECV:pjlink 0

[2019.06.16 14:46:45.306] SEND:%1INST ?

[2019.06.16 14:46:45.476] RECV:%1inst=11 21 31 32 41

[2019.06.16 14:46:45.481] Closed!!!(Disconnect)
[2019.06.16 14:46:46.460] Connected!!!
[2019.06.16 14:46:46.811] RECV:pjlink 0

[2019.06.16 14:46:46.816] SEND:%1NAME ?

[2019.06.16 14:46:47.075] RECV:%1name=Optoma UHD

[2019.06.16 14:46:47.080] 4F 70 74 6F 6D 61 20 55 48 44
[2019.06.16 14:46:47.087] Closed!!!(Disconnect)
[2019.06.16 14:46:48.172] Connected!!!
[2019.06.16 14:46:48.419] RECV:pjlink 0

[2019.06.16 14:46:48.424] SEND:%1INFO ?

[2019.06.16 14:46:48.677] RECV:%1info=UHD

[2019.06.16 14:46:48.683] Closed!!!(Disconnect)
[2019.06.16 14:46:49.580] Connected!!!
[2019.06.16 14:46:49.655] RECV:pjlink 0

[2019.06.16 14:46:49.659] SEND:%1INF1 ?

[2019.06.16 14:46:49.809] RECV:%1inf1=Optoma

[2019.06.16 14:46:49.814] Closed!!!(Disconnect)
[2019.06.16 14:46:50.491] Connected!!!
[2019.06.16 14:46:50.697] RECV:pjlink 0

[2019.06.16 14:46:50.701] SEND:%1INF2 ?

[2019.06.16 14:46:50.955] RECV:%1inf2=Optoma UHD

[2019.06.16 14:46:50.961] Closed!!!(Disconnect)
[2019.06.16 14:46:52.708] Connected!!!
[2019.06.16 14:46:52.960] RECV:pjlink 0

[2019.06.16 14:46:52.965] SEND:%1CLSS ?

[2019.06.16 14:46:53.217] RECV:%1clss=1

[2019.06.16 14:46:53.222] Closed!!!(Disconnect)
[2019.06.16 14:47:00.565] Connected!!!
[2019.06.16 14:47:00.881] RECV:pjlink 0

[2019.06.16 14:47:00.887] SEND:%1ERST ?

[2019.06.16 14:47:01.168] RECV:%1erst=000000

[2019.06.16 14:47:01.214] Closed!!!(Disconnect)
[2019.06.16 14:47:02.182] Connected!!!
[2019.06.16 14:47:02.487] RECV:pjlink 0

[2019.06.16 14:47:02.492] SEND:%1POWR ?

[2019.06.16 14:47:02.580] RECV:%1powr=1

[2019.06.16 14:47:02.585] Closed!!!(Disconnect)
[2019.06.16 14:47:02.846] Connected!!!
[2019.06.16 14:47:03.054] RECV:pjlink 0

[2019.06.16 14:47:03.060] SEND:%1INPT ?

[2019.06.16 14:47:03.288] RECV:%1inpt=41

[2019.06.16 14:47:03.295] Closed!!!(Disconnect)
[2019.06.16 14:47:03.392] Connected!!!
[2019.06.16 14:47:03.635] RECV:pjlink 0

[2019.06.16 14:47:03.640] SEND:%1AVMT ?

[2019.06.16 14:47:03.876] RECV:%1avmt=20

[2019.06.16 14:47:03.881] Closed!!!(Disconnect)
[2019.06.16 14:47:04.034] Connected!!!
[2019.06.16 14:47:04.137] RECV:pjlink 0

[2019.06.16 14:47:04.142] SEND:%1ERST ?

[2019.06.16 14:47:04.308] RECV:%1erst=000000

[2019.06.16 14:47:04.313] Closed!!!(Disconnect)
[2019.06.16 14:47:04.446] Connected!!!
[2019.06.16 14:47:04.705] RECV:pjlink 0

[2019.06.16 14:47:04.709] SEND:%1LAMP ?

[2019.06.16 14:47:04.764] RECV:%1lamp=4 1

[2019.06.16 14:47:04.768] Closed!!!(Disconnect)
[2019.06.16 14:47:04.864] Connected!!!
[2019.06.16 14:47:05.014] RECV:pjlink 0

[2019.06.16 14:47:05.018] SEND:%1INST ?

[2019.06.16 14:47:05.344] RECV:%1inst=11 21 31 32 41

[2019.06.16 14:47:05.349] Closed!!!(Disconnect)
[2019.06.16 14:47:05.437] Connected!!!
[2019.06.16 14:47:05.602] RECV:pjlink 0

[2019.06.16 14:47:05.606] SEND:%1NAME ?

[2019.06.16 14:47:05.686] RECV:%1name=Optoma UHD

[2019.06.16 14:47:05.690] 4F 70 74 6F 6D 61 20 55 48 44
[2019.06.16 14:47:05.693] Closed!!!(Disconnect)
[2019.06.16 14:47:06.024] Connected!!!
[2019.06.16 14:47:06.095] RECV:pjlink 0

[2019.06.16 14:47:06.099] SEND:%1INFO ?

[2019.06.16 14:47:06.329] RECV:%1info=UHD

[2019.06.16 14:47:06.333] Closed!!!(Disconnect)
[2019.06.16 14:47:06.465] Connected!!!
[2019.06.16 14:47:06.549] RECV:pjlink 0

[2019.06.16 14:47:06.553] SEND:%1INF1 ?

[2019.06.16 14:47:06.746] RECV:%1inf1=Optoma

[2019.06.16 14:47:06.750] Closed!!!(Disconnect)
[2019.06.16 14:47:06.935] Connected!!!
[2019.06.16 14:47:07.145] RECV:pjlink 0

[2019.06.16 14:47:07.150] SEND:%1INF2 ?

[2019.06.16 14:47:07.436] RECV:%1inf2=Optoma UHD

[2019.06.16 14:47:07.440] Closed!!!(Disconnect)
[2019.06.16 14:47:07.586] Connected!!!
[2019.06.16 14:47:07.634] RECV:pjlink 0

[2019.06.16 14:47:07.638] SEND:%1CLSS ?

[2019.06.16 14:47:07.798] RECV:%1clss=1

[2019.06.16 14:47:07.801] Closed!!!(Disconnect)

I guess your device responds with lowercase prefixes (e.g. pjlink 0 instead of PJLINK 0). I’ll try to provide a version which is able to handle that till next weekend.

Unfortunately I first need to get my development environment working again after the numerous changes introduced by the ESH integration and new build system, that’s why it will take some time even if it’s only a small adjustment.

Hi @Matthias1,

I’ve built a version which should ignore case when parsing responses from the projector.

It’s available from a different location than usual as it seems like the pull request builder is currently broken.

Please test it and let me know if it resolves the issues you were experiencing.

Best Regards,
Nils

Hi Nils
Thx a lot now it’s works…