[ESPHome] WL-102 Transmitter 433mhz (Solved)

I’m looking for some help with my ESPHome project.

Goal:

I’m trying to control this cat toy which works over 433 MHz.

I thought it was IR when I bought it and realized after purchasing it that it doesn’t need line of sight to work.

I finally took it apart and saw the crystal oscillator that says 6.7458

Something in this thread made me think it’s a 433 MHz device because:
433.92 / 6.7458 = 64.3244685582 – if you know if this confirms the frequency then please let me know!

So that led me down the rabbit hole looking for how to read the 433mhz codes so I can automate the cat toy throughout the day.

I purchased the WL-101 Receiver and WL-102 Transmitter combo on amazon because one of the reviews mentioned ESPHome :smile:

I’m using an ESP32 right now FYI.

I can receive codes just fine.

remote_receiver:
  pin: GPIO 23 
  dump: all
  # Settings to optimize recognition of RF devices
  tolerance: 50%
  filter: 250us
  idle: 4ms
  buffer_size: 2kb

Log:

In this long, I’m just pressing the off button on the remote for a normal tap until it turns off the cat toy. that’s it.

INFO ESPHome 2023.10.6
INFO Reading configuration /config/esphome/cat-toy-controller-esp32.yaml...
INFO Starting log output from cat-toy-controller-esp32.local using esphome API
INFO Successfully connected to cat-toy-controller-esp32.local
[22:06:27][I][app:102]: ESPHome version 2023.10.6 compiled on Nov  4 2023, 22:04:32
[22:06:27][C][wifi:546]: WiFi:
[22:06:27][C][wifi:382]:   Local MAC: B4:E6:2D:FB:1A:7D
[22:06:27][C][wifi:383]:   SSID: 'network name'[redacted]
[22:06:27][C][wifi:384]:   IP Address: 192.168.1.129
[22:06:27][C][wifi:386]:   BSSID: 24:5A:4C:13:5F:2D[redacted]
[22:06:27][C][wifi:387]:   Hostname: 'cat-toy-controller-esp32'
[22:06:27][C][wifi:389]:   Signal strength: -52 dB ▂▄▆█
[22:06:27][C][wifi:393]:   Channel: 1
[22:06:27][C][wifi:394]:   Subnet: 255.255.255.0
[22:06:27][C][wifi:395]:   Gateway: 192.168.1.1
[22:06:27][C][wifi:396]:   DNS1: 192.168.1.1
[22:06:27][C][wifi:397]:   DNS2: 0.0.0.0
[22:06:27][C][logger:416]: Logger:
[22:06:27][C][logger:417]:   Level: DEBUG
[22:06:27][C][logger:418]:   Log Baud Rate: 115200
[22:06:27][C][logger:420]:   Hardware UART: UART0
[22:06:27][C][template.switch:068]: Template Switch 'Power Off Button'
[22:06:27][C][template.switch:091]:   Restore Mode: always OFF
[22:06:27][C][template.switch:057]:   Optimistic: NO
[22:06:27][C][remote_transmitter:015]: Remote Transmitter...
[22:06:27][C][remote_transmitter:016]:   Channel: 3
[22:06:27][C][remote_transmitter:017]:   RMT memory blocks: 1
[22:06:27][C][remote_transmitter:018]:   Clock divider: 80
[22:06:27][C][remote_transmitter:019]:   Pin: GPIO22
[22:06:27][C][remote_receiver.esp32:054]: Remote Receiver:
[22:06:27][C][remote_receiver.esp32:055]:   Pin: GPIO23
[22:06:27][C][remote_receiver.esp32:060]:   Channel: 0
[22:06:27][C][remote_receiver.esp32:061]:   RMT memory blocks: 3
[22:06:27][C][remote_receiver.esp32:062]:   Clock divider: 80
[22:06:27][C][remote_receiver.esp32:063]:   Tolerance: 50%
[22:06:27][C][remote_receiver.esp32:064]:   Filter out pulses shorter than: 50 us
[22:06:27][C][remote_receiver.esp32:065]:   Signal is done after 4000 us of no changes
[22:06:27][C][captive_portal:088]: Captive Portal:
[22:06:27][C][mdns:115]: mDNS:
[22:06:27][C][mdns:116]:   Hostname: cat-toy-controller-esp32
[22:06:27][C][ota:097]: Over-The-Air Updates:
[22:06:27][C][ota:098]:   Address: cat-toy-controller-esp32.local:3232
[22:06:27][C][ota:101]:   Using Password.
[22:06:27][C][api:139]: API Server:
[22:06:27][C][api:140]:   Address: cat-toy-controller-esp32.local:6053
[22:06:27][C][api:142]:   Using noise encryption: YES
[22:07:02][I][remote.canalsatld:100]: Received CanalSatLD: device=0x7F, address=0x1F, command=0x6E, repeat=0x1
[22:07:02][I][remote.pronto:237]: Received Pronto: data=0000 006D 00C1 0000 000F 000B 001C 000D 0006 0005 0029 0003 0004 0007 0020 0016 000A 0014 000A 001A 0010 0010 0009 0005 000D 0013 0003 0006 0004 0019 001C 000C 0002 000E 0002 0019 000A 000F 000D 0016 0008 0002 0021 0005 0020 0006
[22:07:02][I][remote.pronto:239]: 0012 000F 0017 000C 0007 0004 0006 001C 0000 0006 0007 001C 0015 0007 0016 0011 000F 000A 0005 0005 0007 001D 0007 000F 0003 0055 000B 000A 001E 0004 0005 000F 001B 0005 0016 000A 0041 0003 0004 000D 000C 000C 0009 0008 0008 001D 0003 0005 0008 000D 001D 000D 0008 0017 0005 0004 0008 000D 0005 0006 0008 0034 0002 000B 0009 0009 0002 0005 000E 0006 0007 0004 001F 0004 0012 0013 0010 000B 0013 0002 0001 0009 000B 000C 0012 0006 0005 0006 0022 0005 000D 000B 0010 0018 0008 0015 
[22:07:02][W][component:214]: Component remote_receiver took a long time for an operation (0.09 s).
[22:07:02][W][component:215]: Components should block for at most 20-30ms.
[22:07:02][I][remote.pronto:237]: Received Pronto: data=0000 006D 0019 0000 0014 002B 0030 0010 0011 002E 0011 002E 0010 002F 002E 0012 000F 0030 002D 0013 000E 0031 000F 0030 002D 0013 000E 0031 000E 0030 000F 0030 002D 0013 000E 0031 000E 0031 000E 0031 000E 0031 000F 0030 000F 0030
[22:07:02][I][remote.pronto:239]: 000E 0031 002D 0012 002D 0013 000E 009B 06C3
[22:07:02][I][remote.drayton:209]: Received Drayton: address=0x6366 (0xc6cc), channel=0x001 command=0x018
[22:07:02][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=2 data='010001010010001000000011'
[22:07:02][W][component:214]: Component remote_receiver took a long time for an operation (0.06 s).
[22:07:02][W][component:215]: Components should block for at most 20-30ms.
[22:07:02][I][remote.pronto:237]: Received Pronto: data=0000 006D 0019 0000 0014 002C 0030 0010 0011 002F 0010 002F 0010 002F 002E 0012 000F 0030 002D 0013 000E 0031 000F 0031 002D 0013 000E 0031 000F 0030 000F 0030 002D 0013 000E 0031 000E 0031 000E 0031 000E 0030 000F 0031 000E 0031
[22:07:02][I][remote.pronto:239]: 000F 0030 002E 0012 002D 0013 000E 009B 06C3
[22:07:02][I][remote.drayton:209]: Received Drayton: address=0x6366 (0xc6cc), channel=0x001 command=0x018
[22:07:02][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=2 data='010001010010001000000011'
[22:07:03][I][remote.pronto:237]: Received Pronto: data=0000 006D 0019 0000 0013 002C 0031 0010 0011 002E 0011 002F 0010 0030 002D 0012 000F 0030 002D 0013 000E 0031 000E 0030 002D 0012 000E 0031 000E 0031 000E 0031 002D 0013 000E 0032 000E 0031 000E 0031 000E 0031 000E 0031 000F 0030
[22:07:03][I][remote.pronto:239]: 000F 0030 002D 0013 002D 0013 000E 009B 06C3
[22:07:03][I][remote.drayton:209]: Received Drayton: address=0x6366 (0xc6cc), channel=0x001 command=0x018
[22:07:03][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='010001010010001000000011'
[22:07:03][W][component:214]: Component remote_receiver took a long time for an operation (0.05 s).
[22:07:03][W][component:215]: Components should block for at most 20-30ms.
[22:07:03][I][remote.pronto:237]: Received Pronto: data=0000 006D 0019 0000 0014 002C 0030 0010 0011 002F 0010 002F 000F 0030 002E 0012 000F 0030 002D 0013 000F 0030 000F 0030 002D 0012 000E 0031 000E 0031 000E 0031 002D 0014 000D 0031 000E 0031 000E 0031 000F 0030 000F 0030 000F 0030
[22:07:03][I][remote.pronto:239]: 000F 0030 002D 0013 002D 0013 000D 009B 06C3
[22:07:03][I][remote.drayton:209]: Received Drayton: address=0x6366 (0xc6cc), channel=0x001 command=0x018
[22:07:03][I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=2 data='010001010010001000000011'
[22:07:03][W][component:214]: Component remote_receiver took a long time for an operation (0.05 s).
[22:07:03][W][component:215]: Components should block for at most 20-30ms.
[22:07:03][I][remote.pronto:237]: Received Pronto: data=0000 006D 0001 0000 0008 009B 06C3
[22:07:03][I][remote.pronto:237]: Received Pronto: data=0000 006D 0001 0000 0006 009B 06C3
[22:07:03][I][remote.pronto:237]: Received Pronto: data=0000 006D 0005 0000 0003 0048 0002 000F 0007 0037 000D 0068 0007 009B 06C3


The issue I’m having is transmitting the code that I’m seeing in the logs

With transmitting, I can’t get any reaction. I’m wondering if it’s a frequency thing or my code. Love to hear your thoughts on it!

For reference, to turn it on with the remote, it says “hold down for 2 seconds”. I’ve tried increasing the amount of repeats in the code, however it’s causing my esp32 to disconnect from the Home Assistant API and I think the system gets overwhelmed or something. Transmitting the “On” code for 2 seconds is another challenge.

ESPHome YAML:

esphome:
  name: cat-toy-controller-esp32
  friendly_name: cat-toy-controller-esp32

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "secret"

ota:
  password: "secret"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Cat-Toy-Controller-Esp32"
    password: "secret"

captive_portal:
    
remote_receiver:
  pin: GPIO 23 
  dump: all
  # Settings to optimize recognition of RF devices
  tolerance: 50%
  filter: 250us
  idle: 4ms
  buffer_size: 2kb


remote_transmitter:
  pin: GPIO22
  # RF uses a 100% carrier signal
  carrier_duty_percent: 100%

switch:
#### RC Switch Raw
### this is not working
  - platform: template
    name: Power On Button
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000001'
          protocol: 2
          repeat:
            times: 30
            wait_time: 0s #500ms
  - platform: template
    name: Power Off Button
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000011'
          protocol: 2
          repeat:
            times: 30
            wait_time: 0s #500ms
  - platform: template
    name: Slow Speed Button
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000111'
          protocol: 2
          repeat:
            times: 30
            wait_time: 0s #500ms
  - platform: template
    name: 20 Minute Timer Button
    turn_on_action:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000010000'
          protocol: 2
          repeat:
            times: 30
            wait_time: 0s #500ms

#### drayton
### this is also not working
  - platform: template
    name: Power Off Button
    turn_on_action:
      - remote_transmitter.transmit_drayton:
          address: '0x6366'
          channel: '0x001'
          command: '0x018'
          repeat:
            times: 30
            wait_time: 0s #500ms


Let me know if you have any suggestions! Thanks!

@Derek3Rosen let me know if this explains it better and if you can take a look at it

Try and grab a spectrum analyser, like the cheap USB sdr ones. From there you can easily work out what frequency is being used and the codec.

1 Like

Thanks, just purchased a SDR to find out some more info on the radio frequencies

Happened to me yesterday… The only solution I found that really works is to use Tasmota sensors flashed to esp32 / 8266 and use it to read the code, then transmit the code from tasmota to mqtt.
I couldn’t get it to work in esphome.

You need the mqtt addon / integration and the Tasmota integration.

Here is my script code for a RF button / switch that controls a led light

alias: Pacman on-off
sequence:
  - service: mqtt.publish
    data:
      qos: 0
      retain: false
      topic: cmnd/**YOUR_TASMOTA_DEVICE_HERE**/RfSend
      payload: "{\"Data\":\"0x140C01\",\"Bits\":24,\"Protocol\":1,\"Pulse\":390}"
mode: single

info for read the code in tasmota: RF Communication - Tasmota

more info in this thread: ESPHome RF Receiver + Transmitter issues - #3 by dmutpuu.l

2 Likes

@Lainol you’re a legend!

So I ended up flashing the ESP32 with tasmota (using the web flasher) and configured the Rf Receiver on the right pin.

When I pressed the Off button on the remote it returned the following on the tasmota console:

06:26:51.928 MQT: tele/tasmota_FB1A7D/RESULT = {"Time":"2023-11-08T06:26:51","RfReceived":{"Data":"0x452203","Bits":24,"Protocol":1,"Pulse":393}}

I took "Data":"0x452203" and passed it through a hexadecimal to binary converter and the result was 010001010010001000001110 which was the same as the output from ESPHome – so I knew I was on to something. The only difference was Tasmota showed the “Pulse” value and ESPHome did not.

I was able to send the command with Tasmota (from the command line) with this command:
RfSend {"Data":"0x452203","Bits":24,"Protocol":1,"Pulse":393}

Make sure the transmitter pin is configured in Tasmota before trying to send the command.

So I followed the instructions from the post you linked [here] and added the pulse to ESPHome and flashed it to the device. To my surprise, it worked!

Here is the final YAML on an ESP8266

esphome:
  name: cat-toy-controller
  friendly_name: cat-toy-controller

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "123"

ota:
  password: "123"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Cat-Toy-Controller"
    password: !secret wifi_password

captive_portal:
    
remote_receiver:
  pin: D1 ### ESP8266
  dump:
    - rc_switch
  # Settings to optimize recognition of RF devices
  tolerance: 50%
  filter: 250us
  idle: 4ms
  buffer_size: 2kb

remote_transmitter:
  pin: D2 #### ESP8266
  # RF uses a 100% carrier signal
  carrier_duty_percent: 100%

button:
#### RC Switch Raw
  - platform: template
    name: Power On Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000001'
          protocol: 
            pulse_length: 393
          repeat:
            times: 25
            wait_time: 0s
  - platform: template
    name: Power Off Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000011'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: Slow Speed Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000111'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: Random Speed Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000000101'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: Middle Speed Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000001000'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: Fast Speed Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000001001'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: 20 Minute Timer Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000010000'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: 30 Minute Timer Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000010001'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: 40 Minute Timer Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000010010'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: 60 Minute Timer Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000001111'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s
  - platform: template
    name: Timer Off Button
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '010001010010001000001110'
          protocol: 
            pulse_length: 393
          repeat:
            times: 10
            wait_time: 0s

Thanks again @Lainol, @matthew73210, @Derek3Rosen !

2 Likes

Here’s what the dashboard looks like:

Let me know if you have any suggestions for improving it!

Glad it works!!

You can remove or comment the receiver part, no longer needed.

I tried the process thru esphome for nth time… and don’t know why but now is working, but with 5 times repeat, 10 or more are too much for a light, little flicker…

1 Like

I’ve been busy with this for the better part of the day and finally after finding this post I’ve solved it! Thank to @Lainol and @LUNZ! However there where still some gaps in the points here that took me some trial and error to figure out, so I’ve written them out for anyone else that stumbles on to this post (probably me in a year)

  1. Install Tasmota using the web installer Install Tasmota picking Tasmota (english) worked for me
  2. Let it do its thing and when it prompts you give it your Wi-FI credentials
  3. Then visit the device, this you do by going to the IP address. (If you can’t acces the device, try using another browser, for me my laptop browsers didn’t work but my phone did!)
  4. Open the configurations in the web ui
  5. Go to module and select your GPIO pin, for me I’d set it to D32 on my EPS32, so GPIO32 and changed the dropdown to RFrecv (at the same time if you want to test sending a code you can also set your desired pin for RFsend
  6. Then go back to the Main menu and then Tools > Console
  7. Click your remote button a few times and then take note of your code, mine looked like this (this is also is smart moment to test and write down all the other buttons you’ll want to use)
    cpp 13:47:39.080 RSL: RESULT = {"Time":"2025-02-15T13:47:39","RfReceived" {"Data":"0xFFD55F","Bits":24,"Protocol":1,"Pulse":151}}
    (If you now want to test your Data by sending it you can do that by using the input field Enter command `RfSend {“Data”:“0xFFD55F”,“Bits”:24,“Protocol”:1,“Pulse”:151}
  8. Then the result you get in the Data property (for me 0xFFD55F) in to a binary converter which for me gets you 111111111101010101011111, seems to work
  9. Then you can update your ESPhome .yaml file which will look something like this, keeping in mind that you also want to update the pulse_length you got from the Tasmota result in Pulse. Please don’t copy and past the example below, it has some values that need to be specific to your setup
esphome:
  name: remote433
  friendly_name: Remote 433MHz

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "YOUR_KEY"

ota:
  - platform: esphome
    password: "YOUR_PASSWORD"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

captive_portal:
    
# **433MHz Transmitter (TX) on GPIO25**
remote_transmitter:
  pin: GPIO25
  carrier_duty_percent: 100%

# **433MHz Receiver (RX) on GPIO32**
remote_receiver:
  pin: GPIO32
  dump:
    - rc_switch
  tolerance: 100%
  filter: 250us
  idle: 4ms
  buffer_size: 2kb

button:
#### RC Switch Raw
  - platform: template
    name: E on
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '111111111101010101000100'
          protocol: 
            pulse_length: 151
          repeat:
            times: 25
            wait_time: 0s

  - platform: template
    name: E off
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '111111111101010101000001'
          protocol: 
            pulse_length: 151
          repeat:
            times: 25
            wait_time: 0s
2 Likes

First of all, I wanted to thank all of you guys for this great walk-through on setting up a custom ESPHome’s RF Transmitter! Your work helped me to kick-start my own journey.

However, as things are not as easy as they should be, I faced some challenges to make my setup work with ESPHome. So, I wanted to share it with you and everyone else who may stumble upon this topic with a similar problem.

I have a Hampton Bay RF controlled ceiling fan that I wanted to automate using Home Assistant, so I got one of those generic 315 Mhz RF transmitters/receivers from Amazon for hooking it up to an ESP device.

My fan controller is 303.875 Mhz, therefore converting the 315 Mhz RF Transmitter by replacing its “SAW resonator” with the correct one from a spare fan remote would be easier, as all other supporting components on the RF Transmitter board (capacitors, resistors, inductors) would be within the working range for that frequency.

I know I could adapt that spare fan remote and use it directly attached to an ESP to control the fan, but I wanted something compact that would fit inside the junction box behind my control panel tablet. Besides, I wanted to leverage an existing Sonoff Mini R2 which already controls that tablet’s charging outlet. Therefore, I wouldn’t have enough GPIOs to interact with all 5 buttons from the spare fan remote.

Following this topic’s guidance, I used Tasmota to find out each of the remote’s button codes and then converted the Data value to a 12 bits binary (as specified in the Bits value). That was the easy part:

• Light (on/off toggle)

   RSL: RESULT = {"Time":"1970-01-01T00:03:09","RfReceived":{"Data":"0x7E","Bits":12,"Protocol":8,"Pulse":350}}

   12 Bits binary Data: '000001111110'

• Fan Low

   RSL: RESULT = {"Time":"1970-01-01T00:04:41","RfReceived":{"Data":"0x77","Bits":12,"Protocol":8,"Pulse":350}}

   12 Bits binary Data: '000001110111

• Fan Med

   RSL: RESULT = {"Time":"1970-01-01T00:06:32","RfReceived":{"Data":"0x6F","Bits":12,"Protocol":8,"Pulse":350}}

   12 Bits binary Data: '000001101111'

• Fan High

   RSL: RESULT = {"Time":"1970-01-01T00:07:32","RfReceived":{"Data":"0x5F","Bits":12,"Protocol":8,"Pulse":350}}

    12 Bits binary Data: '000001011111'

• Fan OFF

   RSL: RESULT = {"Time":"1970-01-01T00:09:24","RfReceived":{"Data":"0x7D","Bits":12,"Protocol":8,"Pulse":350}}

   12 Bits binary Data: '000001111101'

Although Tasmota’s RFSend command worked flawlessly with all of those codes/protocol/pulses using the exact same string between curly braces (after the “RfReceived” tag), ESPHome didn’t work with the binary equivalent Data, Protocol and Pulse.

I tried several combinations of protocol numbers, pulse values and such, but no go… I even tried hooking up the RF Receiver board to an ESP32 with ESPHome this time, to check the remote’s codes again and I was puzzled to see that ESPHome identified the protocol as # 6, instead of # 8 (as Tasmota did):

I also tried using protocol 6, but that obviously didn’t work. Then I decided to take a look at Tasmota’s RCSwitch.cpp source code in a try to figure out what’s their “secret sauce”, as Tasmota, like Steve Jobs used to say during Apple’s golden age, “It just works”.

The magic line number for me in the code was 123, which lists the values for protocol 8.

Apart from that, between lines 57 and 109 you can find a detailed description of protocols format, which was key for making ESPhome work for me.

You can find the pertinent bits summarized below for protocol # 8:

Tasmota RCSwitch.cpp - Protocol description format:

{ Pulse length, PreambleFactor, Preamble {high,low}, HeaderFactor, Header {high,low}, "0" bit {high,low}, "1" bit {high,low}, Inverted Signal, Guard time }  

{ 320,  0, { 0, 0 }, 1, { 36,  1 }, { 1,  2 }, { 2, 1 }, true, 0 }  // Protocol 08 (Came 12bit, HT12E)

Based on that info, I was able to craft the correct ESPHome configuration for my use case.

In a nutshell, apart from the correct 12 Bit binary Data and Pulse, I also had to add sync, zero, one and inverted parameters into ESPHome’s protocol section to match the values used in Tasmota for protocol 8:

  protocol:
    pulse_length: 320 # Pulse Length
    sync: [36, 1] # Header {high,low}
    zero: [1, 2]  # "0" bit {high,low}
    one: [2, 1] # "1" bit {high,low}
    inverted: true # Inverted Signal
  repeat: 
    times: 5
    wait_time: 0ms # Guard Time

Further looking into Tasmota’s RCSwitch.cpp source code, I noticed that they retry the transmission 5 times, using the defined Guard time value between transmissions. That resulted in the repeat block as you can see above.

So, if your setup is not working in ESPHome but works with Tasmota, check the protocol details for the correct parameters to be configured in ESPHome. Those are of utmost importance for your success!

I’m sharing below the config for the Hampton Bay 303.875 Mhz Ceiling Fan Controller/Remote (all dip switches on). It’s working flawlessly for me - Hopefully that can be useful for someone else using a similar setup:

switch:
  - platform: template
    name: "Fan Light"
    icon: "mdi:ceiling-fan-light"
    optimistic: true
    turn_on_action:
      remote_transmitter.transmit_rc_switch_raw: # {"Data":"0x7E","Bits":12,"Protocol":8,"Pulse":320}
        code: '000001111110' # 07E
        protocol:
          pulse_length: 320
          sync: [36, 1]
          zero: [1, 2]
          one: [2, 1]
          inverted: true
        repeat: 
          times: 5
          wait_time: 0ms
    turn_off_action:
      remote_transmitter.transmit_rc_switch_raw: # {"Data":"0x7E","Bits":12,"Protocol":8,"Pulse":320}
        code: '000001111110' # 07E
        protocol:
          pulse_length: 320
          sync: [36, 1]
          zero: [1, 2]
          one: [2, 1]
          inverted: true
        repeat:
          times: 5
          wait_time: 0ms
button:
  - platform: template
    name: "Fan OFF"
    icon: "mdi:fan-off"
    on_press:
      remote_transmitter.transmit_rc_switch_raw: # {"Data":"0x7D","Bits":12,"Protocol":8,"Pulse":320}
        code: '000001111101' # 07D
        protocol: 
          pulse_length: 320
          sync: [36, 1]
          zero: [1, 2]
          one: [2, 1]
          inverted: true
        repeat:
          times: 5
          wait_time: 0ms

  - platform: template
    name: "Fan LOW"
    icon: "mdi:fan-speed-1"
    on_press:
      remote_transmitter.transmit_rc_switch_raw: # {"Data":"0x77","Bits":12,"Protocol":8,"Pulse":320}
        code: '000001110111' # 077
        protocol: 
          pulse_length: 320
          sync: [36, 1]
          zero: [1, 2]
          one: [2, 1]
          inverted: true
        repeat:
          times: 5
          wait_time: 0ms
 - platform: template
    name: "Fan MED"
    icon: "mdi:fan-speed-2"
    on_press:
      remote_transmitter.transmit_rc_switch_raw: # {"Data":"0x6F","Bits":12,"Protocol":8,"Pulse":320}    
        code: '000001101111' # 06F
        protocol: 
          pulse_length: 320
          sync: [36, 1]
          zero: [1, 2]
          one: [2, 1]
          inverted: true
        repeat:
          times: 5
          wait_time: 0ms

  - platform: template
    name: "Fan HIGH"
    icon: "mdi:fan-speed-3"
    on_press:
      remote_transmitter.transmit_rc_switch_raw: # {"Data":"0x5F","Bits":12,"Protocol":8,"Pulse":320}
        code: '000001011111' # 05F
        protocol:
          pulse_length: 320
          sync: [36, 1]
          zero: [1, 2]
          one: [2, 1]
          inverted: true
        repeat:
          times: 5
          wait_time: 0ms

Regards,

MCMLXXVII

1 Like

glad it worked out @mvaneijgen & @mcmlxxvii !!!

1 Like