Hello everyone, I just built a RF433 receiver with a superheterodyne module connected to my ESP32.
I tweaked the configuration to get it working with my sensors and managed to make through it receiving the code sent from the sensors.
Now, here’s my code that receive the data from the sensors and send it to HA through event bus (only 1 time per code):
remote_receiver:
pin:
number: GPIO27
mode: INPUT
#inverted: True
dump: #all
#- raw #Print all remote codes in their raw form. Also useful for using arbitrary protocols.
- rc_switch #Decode and dump RCSwitch RF codes.
# Settings to optimize recognition of RF devices
tolerance: 50%
filter: 250us
idle: 3ms
on_rc_switch:
then:
- if:
condition:
or:
- lambda: |-
char strHex[100];
sprintf(strHex, "%x", x.code);
std::string sCode = strHex;
std::string sPreviusCode = id(last_command_code);
int timenow = id(sntp_time).now().timestamp;
if (sCode != sPreviusCode || (timenow - id(last_command_time)) > 1)
{
id(last_command_code) = sCode;
id(last_command_time) = timenow;
return sCode.size() == 6;
}
id(last_command_time) = timenow;
return false;
then:
- lambda: 'char str[100]; sprintf(str, "%X", x.code); id(rf433_last_code).publish_state(str);'
- homeassistant.event:
event: esphome.rf_code_received
data:
code: !lambda 'char str[100]; sprintf(str, "%X", x.code); std::string sCode = str; return sCode;'
text_sensor:
- platform: template
name: "RF433 Last code"
id: "rf433_last_code"
icon: "mdi:waveform"
filters:
- to_upper:
globals:
- id: last_command_time
type: int
restore_value: no
initial_value: '0'
- id: last_command_code
type: std::string
restore_value: no
initial_value: '""'
time:
- platform: sntp
id: sntp_time
timezone: Europe/Rome
I needed this “filter” because the same code is received from the sensor many times:
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:38][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='101110011001011001110011'
[08:17:39][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='10111001100101100111001'
As you can notice, the last code always misses a bit, so I just want to say: “the code sent from my sensors should always be 24bit-lenght, ignore it if shorter”.
But I found no way to access the “raw data” as showed in the log, in the “on_rc_switch” section.
That’s seems strange to me, because (as per documentation) in the “binary_sensor” section you can just use “rc_switch_raw”.
I expect your codes are always sent certain defined times, you can use that as a filter. Or simply filter out everything after first received one for x milliseconds.
Another option is to print to log what you receive to have better idea. I haven’t played with this, but you could print x or x.code or x.data. You could try also x.size (I don’t know if it’s valid parameter).
Also, are you sure your signal can’t be decoded with some “real” protocol?
Thank you, unfortunately there’s no parameter “size” (see ESPHome: esphome::remote_base::RCSwitchData Struct Reference), only “code” and “protocol” are exposed.
Also for some reason “code” is a uint64, so does not accept too long codes if received
It’s a mistery for me why they decided to decode the “binary_string”, and to not also expose it as a parameter of the struct.
No documentation is provided with the sensor, so I’m not sure if there’s a particular “hi-level” protocol to decode the data, it’s only a basic door/window sensor. I will try other sensors of the same type to see if I can find a common struct for the message.
How did you configure your transmitter side for sending those sensor values?
Maybe i’m overlooking it but, i dont see any sensor values being sent here. I see rc_switch codes being given a timestamp and that timestamp being assigned to a global and finally a text sensor that just displays the last hex string code it received…
What kind of sensor values are receiving as 6 digit hex strings and i assume your converting them to text or decimal values?
You’ve got me curious with what your up to and im not sure if your plotting something that requires me to keep an eye on you or if i need to tell on you!! Who do you work for? What is your mission?!?!
Lol jk. I am curious with what your ultimately trying to do though and if you wouldn’t mind filling me in, id appreciate it.
Oh, I wrote sensor but the transmitter is just a basic contact sensor (not built by me, I bought it), that notify with a specific code each of those events (without any additional information):
open (contact lost)
close (contact restored)
tampering (rear switch released)
low battery
So no real meaning behind those codes, I just need to “take as given” and use them as triggers to sensors states and automations
It’s only for the love to do things as best as possible that I was trying to send to HA only the codes that I know that are sent from those sensors (RAW code length = 24 bit) and I was curious about the reason that ESPHome does not provides access to RAW code inside the “on_rc_switch” (but it logs it!)
Unfortunately it does not works, because “x.code” is and “already interpreted” value.
I mean, if I receive “01010101” or if I receive “1010101”, the “x.code” value is still 55… But those are 2 completely different codes as RAW, because the second one is probably a truncated value which I should discard because it can be “01010101” or “11010101” or “10101010” or “10101011”
Regarding the time-based filter, I already implemented it in the code above (I just need to remove from the “if” the check about different “x.code”, and it becomes a pure time-based), I just wanted to know if there’s a better way to filter dirty data
If I use this method, I have to map every single code, editing the firmware every time I add a new sensor. If I could just filter based on length of the RAW code, I can just manage all the codes in HA. It’s just that is “cleaner”, in my opinion
Oh, so you basically have all binary sensors then? This is much simpler than you probably thought it was. You just need to make a binary_sensor for each of the possible rc_switch codes you expect to receive like, Open, Close, Tampering/On, Low Battery/On…
Using the delayed_off will also weed out all those additional repetitive codes you receive and the state change times will automatically be logged in the entities history through HA.
Most of us are picky too but only when it’s justified. The way your trying to do a simple task and unnecessarily overcomplicating it and creating additional entities like a text sensor that displays the rc_switch code, it has no practical use and i suspect that you arent planning to memorize each one of the potential codes that could be displayed by that text sensor to even do anything with it and not to mention. It’s of 0 value to see the code because the only thing important or relevant is what that code signifies and thats precisely where the binary_sensor comes in because, that’s exactly what it does for you without all that nonsense and going through 10 extra steps to only end up with the exact same results…