Lutron Occupancy Sensor Not Reporting State

I’ve recently added the new Lutron PD-OSENS-WH occupancy sensors to my Caseta setup. My configuration is

Thing lutron:occupancysensor:laundrymotion (lutron:ipbridge:bridge1) [ integrationId=57 ]
Thing lutron:occupancysensor:downstairshallwaymotion (lutron:ipbridge:bridge1) [ integrationId=58 ]
Thing lutron:occupancysensor:livingroommotion (lutron:ipbridge:bridge1) [ integrationId=59 ]
Thing lutron:occupancysensor:pantrymotion (lutron:ipbridge:bridge1) [ integrationId=60 ]

Switch Lutron_LaundryRoomMotion          "[%s]"          { channel="lutron:occupancysensor:laundrymotion:occupancystatus" }
Switch Lutron_DownstairsHallwayMotion          "[%s]"          { channel="lutron:occupancysensor:downstairshallwaymotion:occupancystatus" }
Switch Lutron_LivingRoomMotion          "[%s]"          { channel="lutron:occupancysensor:livingroommotion:occupancystatus" }
Switch Lutron_PantryMotion          "[%s]"          { channel="lutron:occupancysensor:pantrymotion:occupancystatus" }

I’ve also tried it as:

Bridge lutron:ipbridge:bridge1 [ REDACTED ] {
	Thing occupancysensor laundrymotion [ integrationId=57 ]
	Thing occupancysensor downstairshallwaymotion [ integrationId=58 ]
	Thing occupancysensor livingroommotion [ integrationId=59 ]
	Thing occupancysensor pantrymotion [ integrationId=60 ]

Switch Lutron_LaundryRoomMotion          "[%s]"          { channel="lutron:occupancysensor:bridge1:laundrymotion:occupancystatus" }
Switch Lutron_DownstairsHallwayMotion          "[%s]"          { channel="lutron:occupancysensor:bridge1:downstairshallwaymotion:occupancystatus" }
Switch Lutron_LivingRoomMotion          "[%s]"          { channel="lutron:occupancysensor:bridge1:livingroommotion:occupancystatus" }
Switch Lutron_PantryMotion          "[%s]"          { channel="lutron:occupancysensor:bridge1:pantrymotion:occupancystatus" }

From what I can tell from the documentation my syntax is correct. All of my other Lutron devices work. These simply don’t report any state. Am I missing something here?

Hi. Those Caseta occupancy sensors are very new, so you may be the first to try them with the binding. Try setting the logging level for the lutron binding (org.openhab.binding.lutron) to DEBUG. Then you should be able to see what messages the binding receives from the bridge when the sensors are triggered.

The current occupancy sensor thing handler, which is designed to work with RA2 and HWQS systems, is looking for message like these:
“~DEVICE,10,2,3” would mean that the sensor with integration ID 10 shows occupied (3).
“~DEVICE,10,2,4” would mean that the sensor with integration ID 10 shows unoccupied (4).

It’s possible that the messages you are getting from Caseta are different somehow.

I’ve had it running all morning and while I see all of my switches/dimmers/etc I don’t get anything for any of the 4 motion sensors. I can clearly see the lights they are tied to coming up and down. Just nothing from the integration IDs tied to my sensors. Should I open an issue on github to track? Is there anything special I need to run to get them to display?

One thing I do see is that the room occupancy state seems to be readable in the app. I noted on the documentation that the other systems don’t allow you to query this. I wonder if this is a difference with Caseta.

So you don’t see any messages coming across that look like “~DEVICE,10,2,3” or “~DEVICE,10,2,4” (assuming that 10 is the integration ID of one of your sensors? That makes things difficult.

I would probably try to telnet directly in to the bridge, so that you get an “unfiltered” view of the messages coming out, and also so you can try sending commands.

You could try querying the state of one of the sensors using the command “?DEVICE,10,2” (again assuming 10 is the integration ID you want). This wouldn’t work on a RA2 or HWQS system, but maybe it will on Caseta. The integration protocol for Caseta is helpfully undocumented, although generally a subset of the RA2/HWQS protocol.

It’s also possible that Caseta is reporting on occupancy groups instead of the individual sensor devices. Do you see any messages like the following?

where status = 3 (occupied), 4 (unoccupied), or 255 (unknown)

You can also, in theory, query an occupancy group by sending the command:
?GROUP,<group number>,3

It could be, but the Lutron app uses a totally different protocol to communicate with the Caseta bridge, which Lutron seems to only allow partners access to. So unfortunately the app may have access to different functions than the binding.

I’ve tried a few and I’m just getting errors. Is there a help menu or any kind of generic status commands you’re aware of that I can try to use to reverse engineer the protocol?

I’ve done some searching on google and have found very little results. No one seems to be finding an answer to this. I have both a Caseta and an RA2 Select in the house. The majority of them I have tied to a switch so this isn’t super critical. That being said, I have 2 in key areas that I want OH to make smarter decisions on what to do when occupancy is detected. Does the motion sensor for the RA2 Select work properly at this point? If so, what part number is it?

There isn’t nearly as much as I’d like. :slight_smile:
You can take a look at the Lutron Integration Protocol guide. For what you’re interested in, probably pages 33 and 140-141 are the places to start.

While logged in to a RadioRA 2 or HomeWroks system, you can issue a “help” or “??” command to get different help menus. I don’t think there is an equivalent on Caseta, but since I don’t have one I can’t say for sure.

Well, RA2 Select seems to be a sort of cross between a RadioRA 2 system and a Caseta system. Maybe the result of a drunken night of passion between the two at an industry trade show? It looks like it uses the same "Radio Powr Savr " occupancy/vacancy systems as RadioRA 2. But the main repeater/bridge firmware seems more like a derivative of Caseta than of RadioRA 2/HomeWorks QS, so I couldn’t begin to guess how it handles occupancy sensors. From looking at Lutron’s FAQ, it seems to use the concept of occupancy groups, so the ~GROUP messages may be the first place to look.

What info does the JSON file from Lutron’s control app have about the Caseta sensors that you installed?

I’ve tried every combo of commands I can permutate. Nothing seems to work. I get integration IDs in the JSON and they look “normal”. I’ve not found anything on any of the github projects that look like a hint. Any other ideas?

Hi. Sorry for the delayed response. Unfortunately, I can’t think of much else to try. I was hoping that you would get a ~DEVICE or ~GROUP message from the sensor when its state changed, or at least be able to query occupancy group status with a ?GROUP command.

There is one other possibility. The full Lutron Integration Protocol includes a #MONITORING command, which Caseta may or may not support. It allows you to enable/disable certain classes of notifications, some of which may not be on by default. Take a look at page 12 in the integration protocol giude. If Caseta supports some of these options, especially 6, 7, and 13, it may allow you to enable notifications from the sensors that you aren’t currently seeing using a command like “#MONITORING,13,2”. From some past discussions I’ve had I suspect that Caseta does not support this, but it’s worth a try.

I’ve run several scripts now to try and hunt down an answer to this. At the moment I believe it’s not exposed. The only thing that I’m still trying to figure out is how the app is showing a room as being occupied.

Is there a command that effectively says “dump all”?

Not that I know of. As I said before, I believe their app uses a different protocol to communicate with the bridge. So it’s possible that you can’t get occupancy info using the older protocol. Still, it surprises me that you can’t get either occupancy group status or sensor status. Did you try sending some different #MONITORING commands?

#MONITORING seems to reject as if it isn’t even a valid command. My RA2 Select doesn’t seem to have those commands either.

At this point the only thing I think may be an avenue is the occupancy indicator I noticed on the app earlier. Are you aware of any commands related to rooms or spaces? I haven’t been able to identify any. For example I would be interested in doing something like ?ROOM,1,2,3 or something like that to see if that would shed light on it.

That’s unfortunate. I guess they don’t support it in the new implementations.

Well, usually that would be supported with the GROUP command, such as ?GROUP,<int-id>,3 which should get the occupancy status for occupancy group <int-id>. HomeWorks also supports a command “AREA”, that among other things can give occupancy status for a predefined area. The command ?AREA,<int-id>,8 should return the occupancy status for the area with integration ID <int-id>. So you may want to try playing with that as well.

?GROUP and ?AREA just reply with an error 6 which I believe means no such command.

Different attack path. I have not been able to find where lutron keeps the firmware for their Caseta hubs online. If we could find that, I would think that a strings dump of the code may help us get a list of all of the valid commands (it would be somewhat manual) so that we could see what they used. Any idea on where the images are stored?

I’ve done some checking on the hub itself. I did a port span on my switch and pulled pcap when my phone reached out to the hub on app start. It looks like my phone established a direct TLS connection to the hub on port 8081. I believe what we are looking for may be buried inside of that connection and not exposed over the telnet connection. I’m working on seeing if I can reverse the command structure now to see what it gives me.

Stream of consciousness through debuging.

Use that to generate the 3 files necessary to connect to your bridge.

curl -k --cacert caseta-bridge.crt --key caseta.key --cert caseta.crt https://bridge-ip:8081

When I connect to that I get:
{“CommuniqueType”:“SubscribeResponse”,“Header”:{“StatusCode”:“204 NoContent”,“Url”:"/device/status/deviceheard"}}
{“CommuniqueType”:“ExceptionResponse”,“Header”:{“MessageBodyType”:“ExceptionDetail”,“StatusCode”:“400 BadRequest”},“Body”:{“Message”:“Invalid json.”}}
{“CommuniqueType”:“ExceptionResponse”,“Header”:{“MessageBodyType”:“ExceptionDetail”,“StatusCode”:“400 BadRequest”},“Body”:{“Message”:“Invalid json.”}}
{“CommuniqueType”:“ExceptionResponse”,“Header”:{“MessageBodyType”:“ExceptionDetail”,“StatusCode”:“400 BadRequest”},“Body”:{“Message”:“Invalid json.”}}
{“CommuniqueType”:“ExceptionResponse”,“Header”:{“MessageBodyType”:“ExceptionDetail”,“StatusCode”:“400 BadRequest”},“Body”:{“Message”:“Invalid json.”}}
{“CommuniqueType”:“SubscribeResponse”,“Header”:{“StatusCode”:“204 NoContent”,“Url”:"/zone/status/deprecated/level"}}

The connection at that time does NOT drop. It seems to work like the telnet connection. I get the following on a light that is not attached to an occupancy sensor on and then off:

{“CommuniqueType”:“ReadResponse”,“Header”:{“MessageBodyType”:“OneZoneStatus”,“StatusCode”:“200 OK”,“Url”:"/zone/12/status/level"},“Body”:{“ZoneStatus”:{“href”:"/zone/12/status",“Level”:100,“SwitchedLevel”:“On”,“Zone”:{“href”:"/zone/12"},“StatusAccuracy”:“Good”}}}
{“CommuniqueType”:“ReadResponse”,“Header”:{“MessageBodyType”:“OneZoneStatus”,“StatusCode”:“200 OK”,“Url”:"/zone/12/status/level"},“Body”:{“ZoneStatus”:{“href”:"/zone/12/status",“Level”:0,“SwitchedLevel”:“Off”,“Zone”:{“href”:"/zone/12"},“StatusAccuracy”:“Good”}}}

When I turn a light that is attached to a sensor on/off I get the same thing. I don’t ever see anything that indicates the room’s occupancy status. I would assume that it could be queried however in a similar way. One thing I have noticed is that in some cases the integration ID matches what I would expect, in other instances the integration ID has nothing to do with either the switch or the occupancy sensor ID.

Dimmers seem to show a little differently:
{“CommuniqueType”:“ReadResponse”,“Header”:{“MessageBodyType”:“OneZoneStatus”,“StatusCode”:“200 OK”,“Url”:"/zone/17/status/level"},“Body”:{“ZoneStatus”:{“href”:"/zone/17/status",“Level”:100,“Zone”:{“href”:"/zone/17"},“StatusAccuracy”:“Good”}}}
{“CommuniqueType”:“ReadResponse”,“Header”:{“MessageBodyType”:“OneZoneStatus”,“StatusCode”:“200 OK”,“Url”:"/zone/17/status/level"},“Body”:{“ZoneStatus”:{“href”:"/zone/17/status",“Level”:0,“Zone”:{“href”:"/zone/17"},“StatusAccuracy”:“Good”}}}

If you are good with Python, you may want to take a look at pylutron-caseta. It looks like the latest commit there #41 adds some sort of support for subscribing to occupancy group status. You can also see in the test json files what some responses regarding the occupancy sensors presumably look like.

The problem, of course, is that while in theory support for this new protocol could (and maybe should) be added to the Lutron binding, in practice it would be a big project. At a minimum, it would require developing a new bridge handler with the new protocol support, and doing a bit of re-factoring on everything else in order to abstract away the specific protocol used from the various device handlers. It may almost be easier to create an entirely new binding for Caseta, which is what I believe the folks who maintain the Lutron code for HA have done.

That’s awesome. I’ve read through their code and it looks pretty cut and dry. My problem right now is figuring out how to send the requests upstream easily for testing. They have some example json in the repo that I should be able to figure out. I’m a fan of testing protocol interaction with things like curl before trying to write complex code around it.

My question would be, do the larger systems also use this protocol also? I would wonder if Lutron is going to depreciate the telnet at some point in favor of an SSL encrypted JSON (which makes 100% sense if they do). If the higher end systems like RA2 do incorporate it, it may make sense to adapt the binding for it. I realize that’s a huge effort. I’m not going to understate that. I’m happy to do testing here to get the protocol pieces tested on Caseta and RA2 select since I have them.

The “Gulliver” systems (RadioRA 2 & HomeWorks QS) don’t support the new JSON-based protocol, at least not directly. In a way that is good, because the older telnet-based Lutron Integration Protocol is open and documented, while the newer protocol is purposely neither. There is a new(ish) bridge device called the Connect Bridge that Lutron is pushing on customers as they phase out the “Home+” app. It appears to accept a new protocol, which may or may not be similar to that used by Caseta/RA2 Select, and communicates with RA2/HWQS systems on the back end. I guess this operates on the theory that more moving parts must be better. :slight_smile: To be fair, it also provides some additional functionality, such as connecting to their cloud service and integration with other devices, although nothing that I personally am interested in. Presumably the older Gulliver hardware didn’t have enough resources to support the new features, hence the extra box.

Anyway, let me know how your experiments with the JSON-based protocol go. It would be great to be able to add support for it.