ESPHome Cat Toy 433 MHz Controller
November 8, 2023Goal:
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.
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
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.
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.
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