[OBSOLETE] LutronPro Caseta v1.0

LutronPro Caseta v1.0

As many of you know, Lutron recently updated their app to support the new RA2Select hub they are putting out. When they did that they removed the SSH access that this and nearly every other 3rd party integration used to use to control the bridge breaking them. While this access isn’t 100% required for those with the Pro bridge, it was still very useful and made things simpler. Thanks to the work of @mathieuh who reverse engineered the new TLS connection, I have been able to update my app to continue to work for both Pro and non Pro Bridges. It does require a new step to get a code for generating the certs which I haven’t been able to automate yet.

Please note that this integration uses the newer Node server and not the Python version I originally created.

Setup Instructions:

  1. Install NodeJs
    Currently my app will not work correctly on Windows due to an issue with auto generating the required certs using OpenSSL. If you are a windows user I hope to have a guide to do it manually very soon and I will post it here.
    On windows just DL and install Download | Node.js
    On a raspberry pi:
    If you have an older Pi (B/B+ etc.) this guide should work: Raspberry Pi + NodeJS | We Work We Play
    If you have a newer Pi(2./3 etc.) try this one (the nodejs instructions are down towards the bottom): Beginner's Guide to Installing Node.js on a Raspberry Pi | thisDaveJ

  2. Assuming you have node installed correctly simply type npm install lutronpro’ at the command line/terminal. This will install the server as well as all it’s dependencies automatically. :slight_smile:

  3. Paste the following url into your web browser and press enter. You should then login using your lutron credentials. You should then see something similar to the picture below. Copy the code. https://device-login.lutron.com/oauth/authorize?client_id=e001a4471eb6152b7b3f35e549905fd8589dfcf57eb680b6fb37f20878c28e5a&redirect_uri=https%3A%2F%2Fdevice-login.lutron.com%2Flutron_app_oauth_redirect&response_type=code

  4. Go to my git repository: GitHub - njschwartz/lutronpro: lutronpro interface for ST using NodeJs and grab the runNodeServer.js file. You can either DL it or just copy the couple of lines of code into a file and name it runServer.js (or any name you want as long as it ends with .js). Make sure you change the two IP address to the correct ones for your network and enter your Lutron Login Info to allow the app to authorize for the new TLS server. Where you see ‘var OAUTHCODE=’ replace it with the code you got in step 2. Place the file wherever you want and then at the command line (in the same directory you saved it) type ‘node runNodeServer.js’

If all goes according to plan the program will automatically generate the correct SSL certificates and use them to connect to your bridge. It will detect if you have a Pro bridge and attempt to connect to the Telnet server as well. You will see a lot of random text fly by as it sets itself up (I will be cleaning a lot of that up in the future but for now don’t worry about it).

  1. In the ST IDE under ‘My SmartApps’ add the new repository ‘njschwartz lutronpro master’ From there install/publish the new service manager SmartApp.

  2. Under ‘My Device Handlers’ using the same repo add the device handlers.

Configure the Smartapp on your phone or tablet
Finally open the ST App > Marketplace > My Apps and find the Lutron Caseta Service Manager. Select it and then wait until it finds your server.

Select it and choose Next and wait until it finds all of your switches and Pico’s.

Select them and choose Next. Now wait for your scenes to appear and select the ones you want.

Hit Done and Done again. That’s it! At this point all your Caseta devices should be available in ST and available to control directly or via other Smartapps, CoRE, etc.

Pico Setup: The Pico’s will appear as a device in the ST list, however alone they cannot do anything. You need to assign the buttons to a function. You can use a smartapp like ButtonController or CoRE/webCoRE to get them to do pretty much anything you could want.

Pico Button Mapping: Pico

Additionally, you can adjust some of the settings in the runNodeServer.js file to alter how the Pico’s respond. The buttons respond as both a pressed event and a held event. You can adjust how long you have to hold a button to trigger the held event. You can also adjust how a held button responds as well. It can either send a single event or multiple events until the button is released (this might be useful if using it to adjust the volume for example). More directions can be found in the comments of the runNodeServer.js file.

That is about it. I have tested this on a raspberry pi, ubunbtu, and a windows machine (directions for windows pending) and it all seems to work. That being said, I am certain bugs will be found and I will respond to them as quickly as possible so please let me know if you find any. Thanks for trying it out!


Thanks for the update. I’m trying to install the new node server.

For step two, I believe it should be ‘npm install lutronpro’ instead of ‘node install lutronpro’.

One suggestion, When display any device’s name, would you please add the area name as well?

For example, while I’m setting up a wall dimmer in “master bedroom”, the Lutron app will ask the name like “Master Bedroom _____”. So I put “Lights”, and it appears as “Master Bedroom Lights” in Lutron app. But it only shows “Lights” in this LutronPro smart app.

But from the device discovery JSON, I can see the “Light” is associated with area “Master Bedroom”. So it is better prepend the area before device name.

Hey thanks for the post. You are correct it should be npm install lutronpro. I fixed it in the instructions. Thanks!

Regarding the second part I am not sure about that. I will have to look and see if I can find that information. I haven’t messed with the new app really either so I will have to look at that as well. If it is feasible to do I will certainly work on it. Thanks!

I don’t use this smartapp for the switches (the official integration works well for me) only for the Picos. However, when Lutron updated their mobile app and added “room” grouping, it messed up my Echo voice commands because it changed the name of the devices similar to what @snailium described above. I think that is what is causing his issue.

It added the room group in front of the light name, so in alexa my “dining room light” became “dining dining room light”. To fix the problem, I had to set the room group to " Dining Room" and the switch name to “Light” and now it works. Something tells me that if I removed and readded my lutron switches it would find the “Dining Room Light” as just “Light” in smartthings.

I already spoke with Lutron about the Echo issue and they are looking into a fix.

@njschwartz I know you said this wont work correctly on Windows, so here I am trying to get it to work :slightly_smiling_face:. Any guidance you can give would be greatly appreciated. This looks awesome and would be thrilled to use my PICO remotes as ST buttons. Below is the steps I have taken, I have limited experience with node.js so not where to start troubleshooting. I did temp open up all ports on the machine to my internal network just to make sure I was not hitting a firewall rule. I also installed the openssl package since you mentioned it does not work correctly due to openssl. At this point I am researching how to manually generate certs but I am way out of my league when it comes to dealing with security certs.

  1. installed Node.js
  2. installed the Lutronpro package via NPM intall
  3. After the install it told me there was an update from 5.3.0 to 5.5.1, I went ahead and did the update (hope this doesn’t cause issues…).
  4. Grabbed the code from the address bar as instructed
  5. Copied the lines code from your runNodeServer.js file to a notepad file and put in my Lutron bridge and ST Hub IP as well as the code from that was created in step 3
  6. Saved the edited notepad file as “runNodeServer.js” and placed in same directory where the Lutron pro package was installed.
  7. Running node.js console as administrator I navigate to the directory where the Lutron pro package was installed and run the command “node runNodeServer.js”
  8. At this point it seems to fail and output the following

node runNodeServer.js
Listening on port 5000…
No certs will attempt to generate them

in get CSR
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);

Error: ENOENT: no such file or directory, open 'C:\Users\cmtho\my-csr.pem’
at Object.fs.openSync (fs.js:653:18)
at Object.fs.readFileSync (fs.js:554:33)
at C:\Users\cmtho\node_modules\lutronpro\lutronpro.js:67:17
at C:\Users\cmtho\node_modules\node-cmd\cmd.js:25:21
at ChildProcess.exithandler (child_process.js:278:5)
at emitTwo (events.js:125:13)
at ChildProcess.emit (events.js:213:7)
at maybeClose (internal/child_process.js:927:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)

  1. After receiving the error, I tried to do an npm install of openssl package using the the command npm install openssl.
  2. Tried “node runNodeServer.js” again and received same error.


OK, here I got the server terminated with the following message.

Received: ~OUTPUT,5,1,0.00

Device update recieved
 likely a manual change
About to exit with code: 1
      throw er; // Unhandled 'error' event

Error: read ETIMEDOUT
    at _errnoException (util.js:1041:11)
    at TCP.onread (net.js:606:25)

Well that would explain it then…I never used the room grouping so haven’t dealt with this. When I get back I will look and see how that works exactly. I assume the integration reports will have a field telling me what ‘room’ something is in so I can use it that way, I hope. Interesting they did that and it broke Echo though…you would think they would have though that through first. lol

@bjthomas09 The issue is that the commands I am using to create the needed files don’t seem to work in windows. So even if OpenSSL is installed it doesn’t actually create the files. I plan to try to figure out a way to make it work, but haven’t had a chance yet. Your best bet in the mean time would be to try to do it on another machine and then copy the certs over to your windows box. It is possible to do it on windows but you have to install openssl and then run all the commands manually for now. I am not home so I cannot give you all that info at the moment or I would. I promise it is something I intend to get fixed as soon as possible though.

@snailium Thanks for the bug report. It looks like a connection timed out. Is this a recurrent issue or the first time you have seen it? I think I know what this issue is, but want to make sure. If it is what I think it will be a pretty easy fix, once I can get to my machine to address it. Let me know if it reoccurs and thanks again!


I just recall I rebooted my router this morning, and my Lutron bridge is connected directly to the router. So it results connection reset. Probably it is not a bug, just an exception needs to be handled.

Here is what I got from the debug message.

{"href":"/device/6","Name":"Pico Door","FullyQualifiedName":["Master Bedroom","Pico Door"],

You can see the difference between “name” and “full qualified name”.

Thanks @snailium. I never noticed that in mine, but I am guessing it is because I have not setup any rooms and thus that field doesn’t exist yet. If that is indeed the case though it will be easy enough to add the Fully Qualified Name. I will just have to think a bit on the best way to implement it.

So what you want is for the name to be called Master Bedroom Pico Door correct? I will work on it as soon as I can…I am away for a bit but when I get back in will be one of the first things I take care of. Thanks again for input.

I’m trying to get this working but when i run the node server for the first time and it tries to generate the certs I get the following error:


throw new TypeError('Expected options to be either an object or a string, ’ +

TypeError: Expected options to be either an object or a string, but got function instead
at throwOptionsError (fs.js:81:9)
at Object.fs.writeFileSync (fs.js:1341:5)
at Request._callback (/usr/lib/node_modules/lutronpro/lutronpro.js:99:7)
at Request.self.callback (/usr/lib/node_modules/lutronpro/node_modules/request/request.js:186:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request. (/usr/lib/node_modules/lutronpro/node_modules/request/request.js:1163:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage. (/usr/lib/node_modules/lutronpro/node_modules/request/request.js:1085:12)
at IncomingMessage.g (events.js:292:16)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)

Any ideas?

@njschwartz I figured this out. I’m guessing the version of NodeJS (v6.11.4) I’m using made changes to the fs api and when calling fs.writeFileSync in the lutronpro.js of your NodeJS server, it was expecting an options flag that is a string.

So when I changed the following lines in the lutronpro.js file

fs.writeFileSync("appCert", JSON.stringify(appCert, null, 2), function(err) {
if(err) {
return console.log(err);
fs.writeFileSync("localCert", JSON.stringify(localCert, null, 2), function(err) {
if(err) {
return console.log(err);


fs.writeFileSync("appCert", JSON.stringify(appCert, null, 2), {flag: "w"}, function(err) {
if(err) {
return console.log(err);
fs.writeFileSync("localCert", JSON.stringify(localCert, null, 2), {flag: "w"}, function(err) {
if(err) {
return console.log(err);

//Added the {flag: “w”} option to the fs.writeFileSync call…

Once I made that change to the lutronpro.js and ran the node app it started up without error. Looks like your instructions would have had you install the latest version of node v8.7.0 which should also see this problem no?

Can you add this fix to support node v6.11.4 since it is the LTS version?


Hey thanks for that info. That is very interesting. I will test and certainly update to support that. What platform are you running it on if I might ask? Just interesting that this is the first time this has come up. Thanks!!

Running on a raspberry pi 3

@njschwartz For the events that occur is it possible to update the device handler to do the following?

Send pushed event once button is pushed for a short period.
Send held event as soon as button is held beyond the push threshold.
Send released event as soon as the button is released coming off a held event.

I’m trying to use this device with webcore to manage lights and use held for gradual dimming however the held events seem to only get sent after i let go of a button. It would be nice for the held event to get sent as soon as a hold is detected and then send a released event after the button is let go.

Hope that makes sense…


Hey Huy! Let me see if I understand what you are asking.

  1. So for a pushed event, currently the event fires as soon as the button is released. You want it to fire before it is released? The issue I see there is if you intended a held event and it fires a pushed event you won’t get what you want.

2/3. I think it would be doable to send the held event as soon as whatever time threshold you select is surpassed and the send a released event once it is released…I will need to peek at the code see.

I guess my question though is what exactly are you trying to do? Are you using the ramping features that are already built in? What I mean is in that runNodeServer.js file you can specify how you want buttons to respond. So instead of holding the button for 1s and releasing and getting a single held event, it will continuously send the held event over and over allowing you gradual control. I did this with both a light dimmer and with my sonos volume. Basically in webCoRE I told it that a held event on this button should increased the volume by say 3%. Then when I hold the button it sends that event over and over until I release it. I should note this works ideally with the arrow button on the Pico (the other buttons won’t send the released event after about 7s causing a runaway ramping scenario). I hope that helps…let me know if you try it or if you have and it didn’t work. Thanks!

No i meant send it when its released after a short interval *as it currently does…

I guess my question though is what exactly are you trying to do?

I was going to start dimming once it sends a “held” and then stop when a “release” is sent

Are you using the ramping features that are already built in?

I didn’t notice this stepping feature because when I held the button i only saw that an event of held was sent when I let go of the arrow buttons, didn’t see it get sent over and over until released. This is using the live logging in the IDE.

Could you share your webCore pistons? for dimming and volume control.


I will certainly share my webCoRE pistons when I get back if needed. Unfortunately, I don’t have access to any of that at the moment (I am out to sea :confused:).

You have to go into the runNodeServer.js file and change how the button responds to get that stepping feature. Look at the example below…basically figure out the device number of your pico and then any button that is listed as ‘true’ will use the ramping/stepping feature instead of just a simple held button. When the button uses the ramping feature it will continuously send the ‘held’ command as often as you want (every 1s, 500ms, or whatever you choose). Then just have webCoRE do whatever you want each time the ‘held’ event is fired. Try that and let me know if you see what I am talking about. Let me know!

var buttonMethods = [
{device: ‘3’,
4: true,
5: true

LOL I totally didn’t pay attention to that section of the runNodeServer.js file. I’m curious how difficult would it be to move this config of how buttons work and response times of the buttons to the deviceHandlers configuration or even the smartapp so you can set this in the smartthings app instead?

I’ll give it a shot as it is implemented and let you know if I have issues with getting the stepping feature to work, thanks.

It certainly is possible to set all of that stuff via the smartapp and then send it all over to the server on startup or a change etc. The truth is I just haven’t had a ton of time to work on it, so I just wanted to get it working and this was the simplest way. There are probably 100+ improvements that could be made if I had the time to do it. I will certainly add this to the list though, it’s a good idea. Let me know how it turns out.

So I set the buttons I want to use the ramping feature and nothing seems to happen. In IDE live logging it only sends the held event once i release the button.

My two button devices are 4 and 5 and i have the following lines in the runNodeServer.js file:

var shortPressTime = 300;
var intervalTime = 100;
var buttonMethods = [
{device: ‘3’,
4: true,
5: true
{device: ‘4’,
4: true,
5: true

Should I be seeing a constant replay of button held every 100ms in the IDE Live log according to my settings?

I’m wondering if there are other issues because of the node version i’m using, can’t seem to find any errors anywhere as the node output doesn’t seem to show anything.