Remote_receiver.on_rc_switch RAW data

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”.

Can anyone help me whit this “problem”?

Thank you

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 :thinking:
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.

Did you try with dump: all
if it get’s recognized on any protocol other than RC-Switch?

Anyway, you could simply use on_rc_switch to call a script , do your automations on script and add a delay for duration of the repetitions.

Edit:
Actually you could try with delay directly on on_rc_switch. I’m not sure if it blocks new triggers from repetitions, but it’s quick to try.

Oh, ok. If you mean that, it’s just RC Switch that works. None of the other (except RAW and Pronto) works

Ok, best from those 3.

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.

What about x.code.size ?

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 :sweat_smile:

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” :slight_smile:

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 :wink:

If you know all the valid codes why don’t you use binary sensor then??

binary_sensor: 
  - platform: remote_receiver
    name: "Remote Input"
    rc_switch_raw:
      code: #your known signal

It gives you much more options and easier filtering…

Yes, I know I can do this, but… I’m a bit picky :joy:

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 :slight_smile:

You know better what fits to your case…

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…

binary_sensor:
  - platform: remote_receiver
    name: "Contact Open"
    id: contact_on
    rc_switch_raw:
      code: '110001011110100000101000'
      protocol: 1    
    filters: 
      - delayed_off: 
          0.25s         
    on_click:      
      then:

  - platform: remote_receiver
    name: "Contact Closed"
    id: contact_off
    rc_switch_raw:
      code: '110001011110100000101000'
      protocol: 1    
    filters: 
      - delayed_off: 
          0.25s
     on_click:
        then:

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…