ESPHome and Liftmaster Security+ 2.0 *receiver*

Anyone aware of a Security+ 2.0 receiver for ESPHome?

I’m using two of these inexpensive 850LM receivers (about $27USD) connected to an ESP32/ESPHome with remotes that cost about $6USD each.

I can use the remotes at a pretty good distance to do whatever on the six different channels. Nice functionality for not much money.

Of course, what would be better for identifying individual remotes would be to have a receiver that passes the remote’s ID to home assistant to decide what to do with that specific remote. I could use and track a large number of remotes in that case.

There is the secplus project for decoding, but I’m only finding where it is used to control a garage door opener similar to the ratgdo project or the GRGDO1 device. But I’m looking more for something like ESPSomfy that listens to what the remotes transmit.

I assusme this has been done before, but not having luck searching today.

So did you try what you get out with basic 315 receiver (if anything)? I’m not familiar with this multi-frequency system, is it transmitting on all frequencies or just single selected one?

Good questions. Google AI, for better or worse, says:

LiftMaster Security+ 2.0 operates on 310MHz, 315MHz, and 390MHz frequencies simultaneously, a “Tri-Band” system that provides advanced security and long-range performance. Unlike older systems that used a single frequency, Security+ 2.0 uses a combination of these narrow-band frequencies for encrypted, rolling codes, making it more secure and compatible with a wider range of older and newer LiftMaster and Chamberlain openers.

I assume the remotes are transmit only, one-way pairing, which I assumed the receiver just remembers the remote’s ID and the rolling code. But, I’m in the dark as I don’t have a 315MHz receiver or an SDR.

The secplus github page does show recieving Security+ 2.0.

I’ve been waiting for an excuse to get an SDR.

What is the goal of this project?

individually identify the remote opening the garage?
simple open/close opertation of the garage?
Use this for purpose other than garage/gate?

Read it and still missed it. Have you considered Bluetooth?
How far range do you need?

Here’s one use case. We have a gate for our neighborhood. For little cost we could give contractors or our delivery drivers their own remote and have it work for a limited number days or hours during the day. (I’m doing that now with six channels.) It would be like a programmable keypad some systems provide, but no stopping to punch in the code and wondering if you need to add # or * after the code.

I’m finding the range is much better than wifi or z-wave LR, so could place a remote in an out building to control lighting (or whatever). Remotes are really inexpensive and come in their own compact package and a little clip, too.

Don’t always have to have a problem to solve first. :wink: I have a few extra battery z-wave buttons I haven’t found a use for — yet.

If you can receive the remote signal with common receiver, makes sense.
If not, whatever keyfobs and receiver could offer that functionality without too complex setup.

im thinking bluetooth keyfobs and esphome bluetooth scanner for presence detection.

ive never tested BTLE range but it may be good enough for you purposes.

Just a little update. I got a cc1101 connected to an ESP32-S2 and have it receiving with ESPHome. But, I don’t know enough to get further.

Stepping back, the secplus library has this example of decoding the received data.

$ ./secplus_rx.py

Security+:  rolling=2320616982  fixed=876029923  (id1=2 id0=0 switch=1 remote_id=32445552 button=left)
Security+:  rolling=3869428094  fixed=876029922  (id1=2 id0=0 switch=0 remote_id=32445552 button=middle)
Security+:  rolling=2731817112  fixed=876029924  (id1=2 id0=0 switch=2 remote_id=32445552 button=right)
Security+:  rolling=2731817116  fixed=876029924  (id1=2 id0=0 switch=2 remote_id=32445552 button=right)
Security+:  rolling=2615434900  fixed=72906373  (id1=0 id0=0 switch=1 pad_id=1478 pin=1234)
Security+:  rolling=2615434904  fixed=595608121  (id1=0 id0=0 switch=1 pad_id=1478 pin=enter)
Security+ 2.0:  rolling=240124680  fixed=70678577664  (button=16 remote_id=1959100928)
Security+ 2.0:  rolling=240124681  fixed=70678577664  (button=16 remote_id=1959100928)
Security+ 2.0:  rolling=240124682  fixed=62088643072  (button=14 remote_id=1959100928)
Security+ 2.0:  rolling=240124683  fixed=66383610368  (button=15 remote_id=1959100928)
Security+ 2.0:  rolling=240124684  fixed=74973544960  (button=17 remote_id=1959100928)

What I’m wondering is if I can use the secplus library and add it to the list of codecs that ESPHome has available for decoding. The goal is to call a script with the button and remote_id values.

If not clear, I’m not interested in the typical use of replaying the codes.

I used the cc1101 component pull request in my YAML, which seemed to work. Well, work in that it printed the received data when I pushed a button on the remote.

Is there any hope to use the secplus.c code in ESPHome? I’m looking at:

15:56:59.194][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.200][I][remote.pronto:233]: 0000 006D 0011 0000 000E 002E 0042 0031 0067 0030 001D 0013 004B 001D 002F 0014 0013 0014 004C 0013 0027 0013 0013 0014 0060 0013 0026 0026 0026 0014 0025 0014 0026 0014 0026 0013 0026 009B 
[15:56:59.237][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.242][I][remote.pronto:233]: 0000 006D 000D 0000 0154 0013 004C 0014 0060 0013 0013 0014 004C 0014 0026 0013 0014 0013 0013 0014 0013 003A 003A 0013 004D 0014 0026 0014 0056 009B 
[15:56:59.266][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.271][I][remote.pronto:233]: 0000 006D 000E 0000 0155 0013 004B 001D 002F 0014 0013 0014 004D 0012 0027 0013 0013 0014 0060 0013 0039 0014 0027 0013 0026 0013 0026 0014 0026 0013 0027 009B 
[15:56:59.309][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.314][I][remote.pronto:233]: 0000 006D 000E 0000 0154 0014 004B 0014 0060 0013 0013 0014 004C 0013 0027 0013 0014 0013 0013 0014 0026 0013 000A 000A 003A 0013 004D 0013 0027 0013 0057 009B 
[15:56:59.337][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.342][I][remote.pronto:233]: 0000 006D 000D 0000 0155 0013 0097 0014 0013 0014 004C 0013 0026 0013 0013 0013 0061 0013 0039 0013 0027 0013 0026 0014 0027 0013 0027 0013 0026 009B 
[15:56:59.382][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.387][I][remote.pronto:233]: 0000 006D 000D 0000 0155 0013 004C 0013 0060 0013 0013 0014 004C 0013 0027 0013 0014 0013 0013 0014 0026 0014 004D 0013 004D 0013 0026 0013 0056 009B 
[15:56:59.392][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.396][I][remote.pronto:233]: 0000 006D 0001 0000 0013 009B 
[15:56:59.915][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.922][I][remote.pronto:233]: 0000 006D 0011 0000 000F 002D 00D9 0030 001C 0026 004B 0030 0009 0013 0012 0014 0039 0027 0013 0027 0013 0014 0026 0061 0012 0027 0012 0027 0012 0028 0012 0027 0012 000B 0009 0014 0026 009B 
[15:56:59.961][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.965][I][remote.pronto:233]: 0000 006D 000F 0000 0108 0030 001D 0013 004B 0014 0060 0014 0012 0014 0039 0027 0026 0014 0013 0014 0013 0013 0027 0013 000A 000A 003A 0039 0026 0014 0026 0013 0056 009B 
[15:56:59.987][I][remote.pronto:231]: Received Pronto: data=
[15:56:59.992][I][remote.pronto:233]: 0000 006D 0010 0000 00BD 0030 0068 0014 001B 001E 004B 0026 0013 0013 004C 0014 0026 0014 0013 0013 0026 001E 001D 0013 0026 0026 0027 0013 0026 0014 0027 0013 0012 0027 0026 009B 
[15:57:00.017][I][remote.pronto:231]: Received Pronto: data=
[15:57:00.022][I][remote.pronto:233]: 0000 006D 0013 0000 0155 0013 001C 000B 0025 0014 0012 000A 002F 000B 000A 0013 0013 0014 004C 0014 0026 0015 0012 0014 0012 0014 0012 000B 000A 003A 0011 0027 0009 001D 0009 000B 0012 0014 0026 0027 0042 009B 
[15:57:00.061][I][remote.pronto:231]: Received Pronto: data=
[15:57:00.067][I][remote.pronto:233]: 0000 006D 0012 0000 0038 0030 0068 002F 0009 0030 001C 0013 0097 0014 0013 0014 004C 0013 0026 0013 0012 0014 0026 001D 001D 0013 0009 000B 0012 0027 0025 0014 0026 0013 0027 0013 0013 0027 0026 009B 
[15:57:00.091][I][remote.pronto:231]: Received Pronto: data=
[15:57:00.094][I][remote.pronto:233]: 0000 006D 000F 0000 0026 000A 0124 0026 0038 0014 0060 0014 0012 0014 004C 0014 0026 0014 0012 0015 0012 0014 0013 0027 004D 0027 001C 000B 0013 0014 0012 0028 0055 009B 
[15:57:00.101][I][remote.pronto:231]: Received Pronto: data=
[15:57:00.105][I][remote.pronto:233]: 0000 006D 0001 0000 0012 009B 

Did you get all that pronto salad from one button press? They are all different lengths…

I think so. You can see that there’s about a half second gap, so maybe it sends two messages for every push.

I’m within range of two garage doors and their receivers. Could it be something responding? Seems very unlikely.

The payload consists of 80 or 128 bits, which are split into two 40- or 64-bit halves transmitted in separate packets.

So that’s what you should receive, two packets of identic length.
You could try with RAW and adjust idle parameter higher.

But I don’t expect you get anything static out if this is the way the bits are scrambled:
"The rolling code is “encrypted” by reversing its binary bits, then converting the resulting number to base 3. Each base-3 digit is converted to 2 binary bits. The fixed code and encrypted rolling code are then interleaved. Finally, the bits are permuted and inverted, with the permutation and inversion pattern depending on the values of particular base-3 digits of the encrypted rolling code."

Is that a response from AI? That’s why I was looking at the secplus library as it seems to decode it.

Obviously, I’m digging around here in the dark. I set up the cc1101 first to receive on 315MHz. But, the FCC doc shows that it can transmit on three frequencies – although some older remote has dip switches that might have set the frequency.

Anyway, I just recompiled for 310MHz and then 390MHz and I get the same thing reported whenever I press the button. Is the remote transmitting on all three frequencies? Is the cc1101 receiver too wide?

[07:06:12.544][C][cc1101:256]:   Tuner:
[07:06:12.547][C][cc1101:257]:     Output Power: 9.9 dBm
[07:06:12.550][C][cc1101:258]:     Rx Attenuation: 0 dB
[07:06:12.553][C][cc1101:259]:     DC Blocking Filter: 1
[07:06:12.556][C][cc1101:260]:     Frequency: 390000 KHz
[07:06:12.559][C][cc1101:261]:     IF Frequency: 152 KHz
[07:06:12.562][C][cc1101:262]:     Bandwith: 203 KHz
[07:06:12.565][C][cc1101:263]:     Channel: 0
[07:06:12.568][C][cc1101:264]:     Channel Spacing: 199 KHz
[07:06:12.571][C][cc1101:265]:     FSK Deviation: 47 KHz
[07:06:12.573][C][cc1101:266]:     MSK Deviation: 8 KHz
[07:06:12.576][C][cc1101:267]:     Symbol Rate: 4996 Baud
[07:06:12.579][C][cc1101:268]:     Sync Mode: 0
[07:06:12.582][C][cc1101:269]:     Carrier Sense Above Threshold: 1
[07:06:12.585][C][cc1101:270]:     Modulation: 3

For now I’m going to focus on getting ESPHome Builder off my Rpi and onto a faster machine…

Thanks for looking at this.

It’s from the library docs…

Maybe this is an excuse to get an SDR and try the secplus library and see if decoding on that end works.

I didn’t even think about that Pronto – does that mean the ESPHome receiver component is thinking this data looks like Pronto (whatever that is)?

Whatever signal can be printed out as pronto. RAW signal would give much better vision.

Raw seems less clear, with the signed integers… :wink:

[09:14:29.101][I][remote.raw:041]: Received Raw: 375, -1180, 7671, -473, 3951, -492, 2999, -492, 1026, -491, 1011, -477, 1002, -1003, 512, -468, 1035, -463, 268, -251, 493, -489, 1012, -485, 1021, -475, 1025, -474, 1260
[09:14:29.139][I][remote.raw:041]: Received Raw: 2475, -1218, 5187, -491, 1975, -494, 496, -745, 270, -474, 516, -490, 516, -490, 2020, -473, 1003, -264, 270, -473, 1008, -495, 508, -482, 506, -499, 508, -742, 271, -474, 515, -490, 2520, -470, 1028, -491, 750
[09:14:29.178][I][remote.raw:041]: Received Raw: 8895, -481, 3994, -474, 1490, -748, 761, -994, 492, -490, 1011, -485, 1521, -486, 507, -483, 1022, -474, 269, -250, 493, -489, 1011, -485, 1023, -482, 1013, -474, 1279
[09:14:29.216][I][remote.raw:041]: Received Raw: 8909, -961, 1488, -498, 1498, -471, 533, -489, 499, -483, 2022, -500, 1489, -491, 1026, -491, 514, -466, 539, -467, 1541, -455, 517, -498, 2513, -480, 1031, -467, 773
[09:14:29.255][I][remote.raw:041]: Received Raw: 8888, -481, 3995, -455, 3014, -482, 1022, -489, 1010, -491, 1498, -487, 507, -485, 1022, -476, 268, -252, 492, -490, 1011, -484, 1022, -475, 1025, -474, 1268
[09:14:29.295][I][remote.raw:041]: Received Raw: 8894, -962, 1489, -498, 1498, -471, 533, -489, 499, -481, 2023, -499, 1490, -491, 1025, -490, 515, -490, 514, -468, 511, -261, 769, -475, 513, -473, 268, -250, 2006, -478, 1027, -472, 774
[09:14:29.296][I][remote.raw:041]: Received Raw: 492

I have a lot to learn…

Not good signals. Something is wrong. But you can recognize parts of it as valid signals alternating 500, 1000, 1500