New PJLink Binding for controlling multiple projector brands/models

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

1 Like

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

Edit: Removed github release link

Hi Nils
Thx a lot now it’s works…

Hi @nils.schnabel,
I tried installing the version org.openhab.binding.pjlinkdevice-2.5.0-SNAPSHOT.jar manually into my openhab 2.5.0.M3 installation. I used the console to install that jar bundle but when starting, it provides the following error:
Error starting bundle 280: Could not resolve module: org.openhab.binding.pjlinkdevice [280]
Unresolved requirement: Import-Package: org.apache.commons.net.util; version="[3.3.0,4.0.0)"

Any ideas ?
Thanks, Daniel.

Hi Daniel,

I assume you downloaded the file from github that I wrote here some posts ago. That’s an outdated build. Because the pull request builder is working again you should download the file from the location mentioned in the opening post of this thread.

I don’t want to copy the link here to avoid that I have to update it everywhere whenever it changes. Please go to the opening post of this thread and download the current JAR using the link on

The lastest JAR can be found here

Best Regards,
Nils

P.S. 2.5.0.M4 will have the binding included, so when it will be released, there won’t be a need for manual installing of JARs any more :slight_smile:

PPS: Just noticed that M4 is already released! So you could also go and update to M4, if that’s an option for you.

1 Like

Excellent. Thanks for the quick answer @nils.schnabel.
It worked ! I upgraded to M4 today and the binding is there and automatically discovered my Optoma beamer.
Just one problem surfaced: I turned on Power_State AutoPoll in the binding settings and the binding goes offline with the following error message in the logs:
" (COMMUNICATION_ERROR): Expected prefix ‘%1POWR=’, instead got ‘%1powr=0’ "
Can I fix this myself with a mapping ?
I had to turn off the Power_State polling again for now.
Thanks for your support :slight_smile:

Cheers, Daniel.

Hi Daniel,

good to know that the version shipped with M4 works for you in general!

The problem you have reported looks similar to an issue that was solved before. I’ll try to provide a new version/jar with a fix till Saturday. (Yay JAR installation! :smiley:)

Best Regards,
Nils