ESPHome Cat Toy 433 MHz Controller

November 8, 2023

Goal:

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

cat toy

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

Something in this thread made me think it must be a 433 MHz device since it's not infrared. So I finally took it apart and saw the crystal oscillator that says 6.7458

cat toy pcb

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

cat toy remote

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

I was able to read the codes no problem, however I was having no luck getting the toy to react to the captured commands I was sending back -- so I created this thread on the Home Assistant Community Forums. As usual, the community came through and one user (@Lainol) suggested using another firmware called Tasmota to read the firmware and use that to issue the commands over MQTT. I'm familiar with Tasmota and used to use it a few years ago. However, I've made the specific design decision to standardize only on ESPHome for my smarthome. So I decided it would just be a temporary firmware flash and back to ESPHome.

Rick Morty

Tasmota Detour

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 @lainol linked [here] and added the pulse to ESPHome and flashed it to the device. To my surprise, it worked!

The Final ESPHome YAML on 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

Home Assistant Dashboard:

Screenshot 2023-11-08 at 12.48.48 PM

Share: