Projector control pages

Long time between posts! I've been meaning to compose this particular entry for a while, but have been swamped with other projects. Now that I've got most stuff under control, I figured I'd put in the effort to do a proper write-up.

Back in 2012 I started working at Lutheran Church of Hope in West Des Moines, Iowa. I was a general-purpose base-level technician; now, I have the utmost privilege of working on many aspects of some of our various mission-critical systems.

One task that was placed in front of me, was to see if there was a way to control projectors from a web browser. I knew there was a way, it was just a matter of "what will it take". At the time, we were using wired remotes as the primary method of controlling them. (Being pro-grade projectors, they were wired/wireless "hybrid" remotes. They had IR LEDs, as well as a TRS port. The TRS port talked serial to the projector, while the IR LEDs would work as standard IR-based remotes do. We had them wired, as many projectors were in locations that would make IR communication impractical at best.)

Eventually, we purchased some devices from Extron, that each came to be known colloquially as an "Extron box". They're little rackmountable things that can talk RS-232 and TCP/IP.

At this point, a little bit of background on Extron might be useful. Extron makes (among other things) these Extron boxes that are designed for control and automation of pretty much anything that can talk serial. They're often used in colleges for control of all sorts of A/V systems, including projectors, screens, TVs, digital signage, DVD players, et cetera. They're designed to be used with an ActiveX webpage, little panels with buttons, and a handful of other control devices. The ActiveX webpage can be slightly customized, and can be used for controlling, as well as viewing the status of, anything the Extron boxes can talk to via a driver. Extron has a plethora of drivers available. If the one you need doesn't exist, just tell them, and they'll make one for you. Makes sense as to why they're so popular with colleges.

Anyhow, back at work. We (the Production department) are very much Mac-based, so anything ActiveX was out of the question as a primary means of communication. This is where I come in.

After scouring the Extron documentation, as well as the documentation for the projectors I was attempting to control, I came across a solution: bypass the driver. That's right - instead of trying to spoof ActiveX requests, as I thought I might need to do, I could use the Extron boxes as a dumb TCP/RS-232 bridge of sorts. After figuring out the syntax, it was a simple matter of adding the serial command at the right spot at the end of a GET request.

Eventually, while functional, we wanted something more. Now, we have full-blown projector control pages that look good, work well, and have yet to fail us. They use JavaScript to issue the GET requests, so the user never leaves the webpage they're on. (It uses a function that uses the XMLHttpRequest() function.)

Below I've included a few screenshots; not all of these are on Extron boxes, but they all use JavaScript and CSS to accomplish their task. The ones that aren't on Extron boxes are no fun to work with; that's a story for another time, if it becomes a requested talking point.

All our current code is on Github; I just recently went through and started refactoring all our existing JavaScript to utilize a more scalable method. Previously, we had been setting every button to an anchor tag with an href of the form http://SOME_IP_ADDRESS/remote-control.html?cmd=W01RS|SERIAL_COMMAND_DATA, whereas now, they all use the form extronBox (roomInBuilding, whichProjector, projectorBrand, actionToPerform). The magic all happens in this file; feel free to have a look. I plan to maintain this as a rather generic file to be used for any given Extron box/connected device pairing; comments/suggestions are welcome.


Some specifics, for those curious:

  • the Extron syntax is http://ip-address/filename/cmd=W[port]RS|[data] for RS-232.
    • Many of our extron boxes have several ports; W01RS would specify "RS-232 port 1", W02RS would specify "RS-232 port 2", etc.
    • the "data" is pretty much verbatim. You can, however, encode binary data by using URL encoding. For example, "%0D" is a carriage return.
  • All the parameters passed to the extronBox() function can either be variable names, or a string (if the string is enclosed in quotes).
  • The function needs to be able to handle variable names as input, so the variables intended for use all have a default value; the default value is basically the string you type when you type the variable. (Examples: bridge == 'bridge'projector_on == 'projector-on'.)
  • Flow of the extronBox() function is as follows:
    • First, populate the variables with more meaningful content than is default. Based on what room we pass to the function, the populateVars() function determines what to set the other variables to. For example, let's say the Bridge's center projector is connected to port 3. populateVars() could set projector_center to '03'
    • After that, determine the device-specific commands. Example: Sanyo projectors have an "off" command of "C01". Using a switch-case block, the command variable is set to 'C01' if the action to perform is power_off.
      • Since Sanyo projectors all like a carriage return after every command, there's a little bit of code right after the switch-case block to add '%0D' to every command string, before it gets sent to the Extron box.
    • Finally, the full string (the URL) is assembled, and the httpGet() function is used to make an AJAX request to the Extron box, executing the requested command.

This work has greatly simplified building projector control pages for me; I hope others might find it useful someday.