Controlling Projectors with PJLink

Fri 30 November 2012 by Peter Ward

I regularly need to control a data projector, and previously the only way to do this has been using a web interface created by the manufacturer. Of course the interface is, while usable, poorly designed, and somewhat sluggish.

Fortunately, there’s a protocol for controlling projectors, PJLink, but unfortunately, there aren’t many implementations (I did find a perl module in my search), so I decided to write my own implementation in Python.

So I did, and it took me just a single morning, which I was quite impressed with. The specification is reasonable simple, and aside from one or two stupid mistakes, implementing it was straight forward. In addition to the Python API, I also wrote a simple command line utility for communicating with the projector, which is probably more useful than the API (since you can throw it into your own shell scripts).

If you want to try it out, you can install it from PyPI using pip.

$ pip install --user pjlink
# or if you're in a virtualenv
$ pip install pjlink

The location of projectors can be specified in ~/.config/pjlink/pjlink.conf (on Linux, see appdirs for your platform):

host = myprojector
port = 4212
password = JBMIAProjectorLink

host = bob

Note this stores your passwords in plain text: this is an indication of what I think of the authentication protocol which PJLink uses. I couldn’t find a specific vulnerability, but I still wouldn’t trust it.

Then, you can use -p to reference the projector in the config file. You can also just specify a host and port manually (but not a password).

# get power state of myprojector:4212 (using password)
$ pjlink -p default power
# get power state of bob:4352 (default port, no password)
$ pjlink -p other power

# for the "default" projector, you can omit -p
# this is the same as the first command
$ pjlink power

# get available inputs
$ pjlink inputs

# get current input
$ pjlink input

# switch to input RGB-1
$ pjlink input RGB 1

And there are many more commands available: everything in the specification is implemented as plainly as possible, so if the projector can do it, my tool supports it.

And for the record, I disclaim any responsibility for inappropriate use of this tool. (because I can think of a few!)