RS-232 Serial device control from SmartThings and MQTT: One man's journey past The Cliffs of Insanity and into calmer waters

requires_server
project_av

(The Viking AKA "Holy Crap You're a Giant!") #1

TL:DR I made a thing do another thing with this thing, and it worked!

Quite a while back, my wife and I converted our 23x15 basement into a movie theater with a projector and motorized movie screen. It’s been a great couple of years, getting plenty of use for everything from Superbowl to Halloween Horror Fests for the neighbors and everything in between.

One of the pieces that was missing was the ability to control the projector from the SmartThings platform. I picked up a Vivitek D963HD business projector for cheap through my workplace when it was removed from use during a remodel. It had less than 100 hours of use on it, so I was beyond thrilled to haul it home and hang it from the ceiling. It features four methods for control: Direct button control, IR Remote, Ethernet (Control 4), or Serial. As no one has made a Control4 to SmartThings bridge yet, the Ethernet option went out the window. When we installed the HTC Vive base stations in the basement, this caused interference with the Harmony remote, so IR control of the projector followed. The main theater components are tucked in the furnace room, so the Harmony Hub is not impeded when IR blasting that equipment. Manual control of the projector in an automated house is anathema, but we’ve basically been living with that for a long time now… It’s time to get things truly integrated.

When we first set this up, a friend of mine wrote a small Python to Serial interpreter, and I ran that on my Raspberry Pi with an HTTP device in SmartThings to control power on/off. I ran into some issues with the Pi, and was never able to get that project running again properly as I had no development experience and couldn’t figure out how to get things to talk the way I want.

I finally decided that enough was enough, let’s make it happen.

Enter: MQTT and Node-Red.

The goal: “Alexa, turn on the movie theater” or “Honey? Would you queue up the Cinema Experience with this movie?”

The hardware:
USB to RS-232 adapter
USB over Ethernet adapters
Vivitek D963HD projector
Intel NUC (serving various purposes other than this project)

The software:
Windows 10
Mosquitto Broker for Windows
Node-Red for Windows
MQTT Bridge for SmartThings
node-red-node-serialport
NSSM (Non-Sucking Service Manager)

I’ve never touched MQTT or Node-Red before, so this was a huge learning experience for me. I’ve had a MQTT broker for a while now, but it was literally just a plugin for HASS.IO on the NUC and I never dug into it beyond the installation. I originally started this project on a Raspberry Pi, but due to my lack of patience, I ended up re-purposing the HASS.IO NUC back to Windows since I planned to use the system for Blue Iris as well as the lower impact Mosquitto, etc.

I won’t provide specific step by steps for installing the necessary software linked above, but I will tell you about the things I encountered that threw me for a loop, node pun intended…

Serial Issues with the Projector API…
For the last several days I’ve been struggling to get serial commands to send the proper carriage returns that the projector requires as part of the command format for controlling all aspects of the device. \r\n, \r, \n, hammering on the keyboard, screaming in frustration… None of it worked. Questions to various Node-Red enthusiasts resulted in no progress, until one hero stepped in and said “based on the debugging logs, have you tried just… not sending a carriage return?” Editing some information in the flow allowed the carriage return to send at an earlier segment of the flow in a Formula, and then changing the Serial port to not Split Input based on character detection resolved this. There is no documentation on this anywhere that I can find, so this is the primary reason I am making this post… Hopefully someone else doesn’t hit the same frustration points as me. Screenshots attached.

In this first image, the MQTT node on the top left listens to the smartthings/Projector/switch topic for an “on” or “off” command from SmartThings. When the command comes through, it moves to the Change node where three rules exist. “Change the message payload from On, Off, or Status, to the proper command for the projector”. See the second image for what this looks like. The now altered message payload then moves on to the Formula node where the payload is altered to contain the correct characters required to establish the Carriage Return and Line Feed that the projector requires to complete the command. See the third image.
The final output to the Serial port is then sent to the projector and the command is completed. The “Split Input” function is where I was struggling. Changing this to timeout instead of look for character and split the command up resolved the serial problems I was encountering. See the fourth screenshot for the fixed settings.




Now that I could control the projector via MQTT, it was time to get it into SmartThings.
I installed the MQTT Bridge on the same Windows based Intel NUC as Node-Red and got it configured to talk to the Mosquitto broker on the system.

I installed the SmartApp and Device Handler within the SmartThings IDE, and then deployed them via the app on my phone. Configuring the MQTT Bridge was super simple. Point it to the broker, slap some devices into it, and you can now control those devices via MQTT.

I created a virtual switch device within SmartThings, named it Projector, and added it to the MQTT Bridge SmartApp, and then turned it on… And did a success-kid fist pump when the projector fired up without issue.

My next piece of the puzzle was to get my Marantz receiver integrated with SmartThings. The Marantz device handler in the community is a great piece of work, but I really only need simplified on/off control when we’re doing movie night. Turn on, set to pre-defined settings, and we’ll be right there with the popcorn.

I installed the Marantz node available from the community, and set it up to receive the same on/off signal that the projector does from MQTT.
In the next screenshot, the same basic flow applies: Receive on/off command from MQTT for Projector, move on to the Delete node to remove the msg.topic (the smartthings/Projector/switch) since it seems to push through the change rule and the receiver does not respond to the command. Then, flow into the Change rule and convert the on/off into receiver usable commands (second screenshot), and finally out to the receiver over HTTP.


That center section between the projector and receiver flows is for feedback from the projector whenever status changes or commands result in a response. I am not yet parsing those…

When all of this was operational, I then configured the Node-RED and SmartThings MQTT Bridge command files to run as a Windows Service using NSSM with the following commands:

Node-Red
nssm install Node-RED “C:\Users\Synthesis\AppData\Roaming\npm\node-red.cmd”
nssm set Node-RED AppDirectory “c:\Users\Synthesis.node-red”
nssm set Node-RED AppParameters “-u C:\Users\Synthesis.node-red > C:\temp\node-red.log”
nssm set Node-RED Description “A wiring tool for the Internet of Things”

SmartThings
nssm install SmartThings-MQTT “C:\Users\Synthesis\AppData\Roaming\npm\smartthings-mqtt-bridge.cmd”
nssm set SmartThings-MQTT AppDirectory “c:\Users\Synthesis.node-red”
nssm set SmartThings-MQTT Description “Bridging the gap between MQTT and SmartThings, one device at a time.”

I’m thrilled that this is operational, but know that I can do so much more. My hold-up is the lack of device handlers with the correct capabilities to properly control the devices. Since MQTT can translate pretty much any command, a generic “Projector” or “TV” device handler would work to provide a more robust device with more control features.

I’ve fallen in love with MQTT and Node-Red, and I’m now looking into all sorts of options for home announcements, etc…


#2

Nice report!

By "serial’, you mean “RS-232 serial communication,” right? not some other proprietary communications protocol?


(The Viking AKA "Holy Crap You're a Giant!") #3

Yes. I should clarify that above, though the hardware list does specifically state USB to RS-232. :slight_smile:


#4

I’d at least suggest changing the topic title to “RS232 Serial Device Control” since I think more people are likely to just search on “RS232” so that way more people will see it. :wink:


(The Viking AKA "Holy Crap You're a Giant!") #5

Good call. Done.


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #6

Certainly an interesting project and the details are useful in understanding the power of the integration of the various software and hardware components you employed.

But, in my experience, … this was “overkill”.

I implemented control of my Epson Projector (over RS-232 and 12v-DC-Out-Signal Wire) by just using an Arduino with SmartThings Shield (now deprecated, but replaceable using Arduino/MCU with WiFi like ESP8266 and Community provided Arduino libraries), and a bare bones RS-232 $12 breakout module for the Arduino.

Upon receiving the “on” signal from SmartThings, the Arduino issues “on[cr]” over the RS-232 using a simple library provided with the module. I repeat it 3 times in case the RS-232 communication is garbled. A minute or so later, the projector indicates success by powering the 12v signal wire, which is lowered by 2 resistors (Ohm’s Law) to 3v, and fed into one of the Arduino digital input ports. This triggers the script to send an “on” message to SmartThings and the DTH issues an “on” Event, closing the feedback loop and confirming the projector has been turned on. This confirmation also works flawlessly if the projector is manually activated (via it’s own IR remote or side-button).

The reverse occurs for “off”.

Meanwhile, the Arduino does double-duty as it is programmed to handled a “screen on” request from SmartThings. This triggers a 433Mhz transmitter module (~$12) to send a code to lower the motorized projection screen. If the screen used an IR remote, an IR module could have been used instead, or, I originally implemented with a 12v relay soldered to the buttons of the screen’s remote control.

The reverse occurs for “screen off”.

Finally, as a failsafe, since I’m using a smart-module anyway (i.e., an Arduino MCU), it can act independently of SmartThings. If it detects the 12v-DC signal input from the Projector, it automatically executes the screen-lowering function.


(The Viking AKA "Holy Crap You're a Giant!") #7

Terry, thanks for adding your project.

I have LITERALLY zero development skill… As in, I have tried learning, but have a real, documented learning disability with languages and syntax. Hardware? Logic? No problems whatsoever. I can do a board level repair, down to micro-soldering and reflows.

The MQTT project: Overkill? Definitely. But it works, gives me a feeling of accomplishment, and I learned something in the process… I’d love to have done this a different way, but I’ve spent the last year trying to learn the basics of programming languages at any level and failing miserably. Logic is easy to follow, syntax is impossible for me, sadly.

I’ll see if I can get one of my esp units running with your sketch, and reach out with any questions.


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #8

Unfortunately my sketch communicates with SmartThings only via the deprecated development Shield.

@ogiewon’s ST Anything library or whatnot could be used to adapt it to an ESP / wifi MCU…


(The Viking AKA "Holy Crap You're a Giant!") #9

I banged my head on ST Anything for a while and got nowhere, sadly. I don’t like to profess my stupidity, so I don’t post much here unless I have a success story.

Eh, either way, I wanted MQTT in the home (and outside) for NeoPixel lighting controls. Since I have several pixel lights at work, my CloudMQTT broker and my Mosquitto at home talk to each other anyway and I can tie the lamps at work into the automation platform.