I got them off of amazon, this was going to be nothing more of a “hmm, wonder if this will work”, but now i’m off to bringing this fan into the 21st century.
https://www.amazon.com/dp/B01DS1WUEQ?psc=1&ref=ppx_yo2ov_dt_b_product_details
I got them off of amazon, this was going to be nothing more of a “hmm, wonder if this will work”, but now i’m off to bringing this fan into the 21st century.
https://www.amazon.com/dp/B01DS1WUEQ?psc=1&ref=ppx_yo2ov_dt_b_product_details
So a bit of an update. I started suspecting I may have fried something in the circuitry with the boards I had. Running them on 5V instead of 3V. I know dumb. Even though they transmitted fine the reception has never been good. So I bought new boards from the link below and a 9 inch quarter wave antenna meant for 315Mhz. So far the results are better from the tests I have done. The remotes are getting picked up from multiple rooms in the house with the unit in a central location. I am still working on the coding as it is quite difficult to ensure the states remain in sync when you are talking about using an RF remote, the HA iOS app, and a wall switch hooked to a Shelly 2.5.
I’m trying to get this up and running and seem to have the same model, if not a very similar model, remote that you have. How did you end up getting this to work? With the pin-out diagram from SmartRC the serial monitor stops working and uploads do as well so I’m flying blind as to what’s going on with the ESP8266 module. I can’t get the receive or send demos working and I’m completely at a loss. The only modicum of success I’ve had so far is when I boot up the module with it wired up to the CC1101 I get an “online” message from home/hamptonbay/status when listening for all MQTT messages in Home Assistant…I would love to hear how you were able to get this up and running as you may be my only hope lol
I’m working with a Wemoss D1 Mini V4.0, and my remote’s model number is TR220A.
I just came accross this searching! I just had to take apart my Hampton Bay fan remote to clean the buttons because some soda got spilled on it and they were sticky. But saw on the circuit board, its so simple, just the UC, a PIN selector and buttons with the RF antenea built into the PCB… Started to think about how to add an ESP32 to this…
While doing some research on the RF 303.9Mhz frequency that the fan uses, I came accross yoiur post and GIThub with all the info already done! LOL. Thank you for this!!! The GITHUB you posted shows the 303.9, but then the RF module in the requirements is a 315-900Mhz and seems like it mainly operates at 433Mhz. your code is for ESP8266, but I’ll just update it to port over for an ESP32… OR I just use up some of my old 8266 boards… But if this works, I’ll design my own PCB’s to plug and play all my fans (6) of them in each room. Since they are wifi, I just need to 3D print a box and run power to them. I may add a MMwave sensor if possible and temp sensor to it too, so I can automate to turn fan on to xx speed if room gets hotter then xx degrees and a the room is occupied. Awesome work on the feedback to be able to verify the fan setting actually set!
Did that board end up working for the RF? 10’ to the next room, was that the max you got, or was only able to test? I would like to build a single device for my house and put the sensor in a single location and then control each room via the PIN selection on the control. I have a 3800sqft house with 6 of the same Hampton Bay 303.9Mhz ceiling fans that are remote.
Is there any plans to update this to the new MQTT format in HA?
It looks like some of the properties are no longer available.
Hello,
The Hampton Bay fans in my home use a remote with model number “HD3”. Looking up the FCCID: “2AAZPHD3” on this website:https://fccid.io/, it shows the frequency is 304.25MHz, which matched what I was seeing with my RTL-SDR using universal radio hacker.
I have been able to decipher the following protocol, and have it working on esphome using dbuezas’ cc1101 template: GitHub - dbuezas/esphome-cc1101
Below is the protocol for the Hampton Bay fans using the HD3 remote using esphome. I send 2 input_select variables to esphome from home assistant, device and command.
api:
encryption:
key: "key"
services:
- service: transmit
variables:
command: string
device: string
then:
- logger.log: "running script"
- script.execute:
id: transmit
device: !lambda return device;
command: !lambda return command;
script:
- id: transmit
mode: queued
parameters:
command: string
device: string
then:
- if:
condition:
lambda: 'return ( device.substr(device.size() - 3) == "fan" );'
then:
- lambda: get_cc1101(transceiver).setFreq(304.25);
- lambda: get_cc1101(transceiver).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
repeat:
times: 5
wait_time: 8.0ms
code: !lambda |-
std::map<std::string, std::string> devices, commands;
devices["room1_fan"] = "0110";
devices["room2_fan"] = "1100";
devices["room3_fan"] = "0111";
devices["room4_fan"] = "0000";
devices["room5_fan"] = "1111";
commands["fan_high"] = "11111110";
commands["fan_medium"] = "11111101";
commands["fan_low"] = "11111100";
commands["fan_off"] = "11111111";
commands["off"] = "01100100";
commands["on"] = "01100101";
commands["light_toggle"] = "11100100";
return ( "1000000000000" + id(devices[device]) + id(commands[command]) );
protocol:
pulse_length: 375
sync: [0,0]
zero: [2,1]
one: [1,2]
inverted: True
- lambda: get_cc1101(transceiver).endTransmission();
# Code breakdown:
# - 13-bit preamble + 4-bit dip settings + 8-bit command
# - preamble: 1000000000000 (1x "1"-bit + 12x "0"-bits)
# - dip settings - as seen in the remote - NOT inverted NOT reversed
# - 8-bit commands:
# - power on (light on, fan high): 01100101
# - power off (light off, fan off): 01100100;
# - toggle light: 11100100
# - fan high: 11111110
# - fan medium 11111101
# - fan low 11111100
# - fan off 11111111;
Again, a reminder if you have an HD3 remote, the frequency is 304.25MHz.
Also, I can control all 5 fans in my house with a single transmitter in the master bedroom - so it’s reaching about 40 ft with no issues - granted my home is only constructed with single wall wood.
I also have the same transmitter controlling my 433.83MHz string lights outside - with the
- lambda: get_cc1101(transceiver).setFreq(xxx.xx);
command prior to transmitting any signal. The same antenna handles both frequencies pretty well.
Hey,
I have the same remote, HD3, 2AAZPDH3 and 304.25MHz. I am trying to go through the process of going through capturing it with URH. Never done this before so I might just be missing something but I am not seeing the same patterns.
What I have captured for pressing the power button is:
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 8082 samples]
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 8083 samples]
1100010001000100010001000100010001000100010001000100010110001011000101101100010001011001011 [Pause: 8081 samples]
1100010001000100010001000100100010001000100010001000101100010110001011011000100010110001011 [Pause: 8078 samples]
110001000100010010001000100010001000100010001000100010110010110001011011000100010110001011 [Pause: 8081 samples]
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 8080 samples]
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 8078 samples]
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 8080 samples]
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 8079 samples]
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011 [Pause: 845449 samples]
I’m don’t think I am seeing the 13 bits of preamble, I can find my dip setting of 0101, but looking before and after it don’t line up.
Any advice on decoding this?
the data is there.
if you define the ‘one bit’ as ‘011’ and the ‘zero bit’ as ‘0001’ and realize that there is actually a 0 before the first 11 that doesn’t show up, then this signal;
11000100010001000100010001000100010001000100010001000101100010110001011011000100010110001011
Translates to the following data bits:
1000000000000010101100101
So preamble is: 100000000000
Then the dip pin is 0101
And the command is 01100101, which is power on.
The only difference between your result and mine is your zero bit has 4 characters where mine was three “001”
Try leaving sample rate as default in URH.
I was wanting to get this to work, but I dont understand how the MQTT FAN changes work and so the original script will not work when setup of the config.yaml file from it. Have you got this working in HA??
Can you share the whole esp code to see how you control the buttons?
I have a similar fan but the light is dimmeable and there is a code for each light status, but i cant find the pattern yet
Received RCSwitch Raw: protocol=6 data=‘000000000000110001100’ only light at 96%
Received RCSwitch Raw: protocol=6 data=‘000000000000110101101’ with fan high
Received RCSwitch Raw: protocol=6 data=‘000000000000111001110’ with fan med
Received RCSwitch Raw: protocol=6 data=‘000000000000111101111’ with fan low
Received RCSwitch Raw: protocol=6 data=‘000000000110010001010’ only light at 50%
Received RCSwitch Raw: protocol=6 data=‘000000000110010101011’ with fan high
Received RCSwitch Raw: protocol=6 data=‘000000000110011001100’ with fan med
Received RCSwitch Raw: protocol=6 data=‘000000000110011101101’ with fan low
my esp code:
esphome:
name: d1-rf
friendly_name: D1 RF
includes:
- cc1101.h
libraries:
- SPI
- "SmartRC-CC1101-Driver-Lib"
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
power_save_mode: HIGH
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "D1-Rf Fallback Hotspot"
password: "0dsO0HAYrNTw"
captive_portal:
sensor:
- platform: custom
lambda: |-
auto my_sensor = new CC1101(
D5, // SCK
D6, // MISO
D7, // MOSI
D3, // CSN
D1, // GDO0
96.96, // bandwidth_in_khz
303.90 // freq_in_mhz
);
App.register_component(my_sensor);
return {my_sensor};
sensors:
id: transciver_1
name: "RSSI"
unit_of_measurement: dBm
entity_category: diagnostic
# you can have multiple transcivers in the same board
# with more than 2, an esp8266 will get out of RAM. You'll need to remove the logger and reduce the recevier buffer size to 200
number:
- platform: template
max_value: 812
min_value: 450
step: 1
mode: slider
optimistic: true
unit_of_measurement: "kHz"
name: BW
on_value:
then:
- lambda: get_cc1101(transciver_1).setBW(x);
- platform: template
min_value: 304.2
max_value: 348
#min_value: 378
#max_value: 464
# min_value: 799
# max_value: 928
step: .001
mode: box
optimistic: true
unit_of_measurement: "MHz"
name: FREQ
on_value:
then:
- lambda: get_cc1101(transciver_1).setFreq(x);
switch:
- platform: template
name: "RSSI"
entity_category: diagnostic
lambda: return get_cc1101(transciver_1).rssi_on;
turn_on_action:
lambda: get_cc1101(transciver_1).rssi_on = true;
turn_off_action:
lambda: get_cc1101(transciver_1).rssi_on = false;
button:
- platform: template
name: Apaga Todo
on_press:
- lambda: get_cc1101(transciver_1).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
code: '000000000000000000000'
protocol: 6
repeat:
times: 3
wait_time: 0s
- lambda: get_cc1101(transciver_1).endTransmission();
- platform: template
name: Fan Off
on_press:
- lambda: get_cc1101(transciver_1).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
code: '000000000110000000110'
protocol: 6
repeat:
times: 3
wait_time: 0s
- lambda: get_cc1101(transciver_1).endTransmission();
- platform: template
name: Fan Low
on_press:
- lambda: get_cc1101(transciver_1).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
code: '000000000110001101001'
protocol: 6
repeat:
times: 3
wait_time: 0s
- lambda: get_cc1101(transciver_1).endTransmission();
- platform: template
name: Fan Med
on_press:
- lambda: get_cc1101(transciver_1).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
code: '000000000110001001000'
protocol: 6
repeat:
times: 3
wait_time: 0s
- lambda: get_cc1101(transciver_1).endTransmission();
- platform: template
name: Fan High
on_press:
- lambda: get_cc1101(transciver_1).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
code: '000000000110000100111'
protocol: 6
repeat:
times: 3
wait_time: 0s
- lambda: get_cc1101(transciver_1).endTransmission();
remote_transmitter:
- pin: D1 # This is GDO0
carrier_duty_percent: 100%
remote_receiver:
- pin: D1 # This is GDO0
# on the esp8266 use any of D1,D2,D5,D6,D7,Rx
# Don't use D3,D4,D8,TX, boot often fails.
# Can't be D0 or GPIO17 b/c no interrupts
dump:
- rc_switch
# Settings to optimize recognition of RF devices
tolerance: 50%
filter: 250us
idle: 4ms
buffer_size: 2kb
@jbrande
Not sure whose yaml you wanted, but I added a bit more to my post so you can see how I tackled the issue.
I didn’t use buttons. I defined a service in esphome which is callable from inside HA with the parameters of ‘device’ and ‘command’. I then just call that service either in automations or with the UI.
@jbrande
Another note - with your receiver tolerance set at 50%, there is a very good chance your remote is not rc_switch protocol 6.
I recommend buying an rtl-sdr to analyze the signal before trying to duplicate it with a cc1101. It’ll save a lot of guesswork.
Just wanted to say thanks, this post pointed me in the right direction, and I finally got it working. SDR + URH + ESPHOME + dbuezas’ cc1101 template is the way. URH is really cool.
I made a more analog version of this. By means of slaving the remote to an ESP32 and adding a light sensor for the light sync check.
substitutions:
device_name: 'mbr-fan-remote'
friendly_name: mbr-fan-remote
device_comment: "located in the bedroom"
entity_prefix: "MBR"
packages:
core: !include _config/core.yaml
esphome:
name: mbr-fan-remote
friendly_name: mbr-fan-remote
on_boot:
priority: 800
then:
- script.execute: check_light_sync
esp32:
board: esp32dev
framework:
type: arduino
api:
encryption:
key: "kBt+Rva8i/RSsJNYNx+wnM5MhdGnfX8oEIcK0OcJe7o="
logger:
level: DEBUG
i2c:
sda: GPIO16
scl: GPIO17
scan: True
sensor:
- platform: bh1750
id: light
device_class: illuminance
state_class: measurement
internal: True
address: 0x23
update_interval: 500ms
accuracy_decimals: 1
output:
- platform: template
id: fanoutput
type: float
write_action:
- lambda: ""
- platform: gpio
pin:
number: GPIO25
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: light_out
- platform: gpio
pin:
number: GPIO14
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: reverse_out
- platform: gpio
pin:
number: GPIO23
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan1_out
- platform: gpio
pin:
number: GPIO18
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan2_out
- platform: gpio
pin:
number: GPIO19
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan3_out
- platform: gpio
pin:
number: GPIO21
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan4_out
- platform: gpio
pin:
number: GPIO27
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan5_out
- platform: gpio
pin:
number: GPIO26
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan6_out
- platform: gpio
pin:
number: GPIO22
inverted: true
mode: OUTPUT_OPEN_DRAIN
id: fan0_out
switch:
- platform: template
id: light_toggle
name: Fan Light
optimistic: True
turn_on_action:
- button.press: btn_light
- delay: 1s
- script.execute: check_light_sync
turn_off_action:
- button.press: btn_light
- delay: 1s
- script.execute: check_light_sync
fan:
- platform: speed
output: fanoutput
id: mbr_fan
name: "Master Bedroom Ceiling Fan"
speed_count: 6
on_turn_off:
- lambda: |-
id(btn_fan0).press();
on_speed_set:
- lambda: |-
if (id(mbr_fan).state == 0) { /* Fan is off, do nothing */ }
else if (id(mbr_fan).speed == 1) { id(btn_fan1).press(); }
else if (id(mbr_fan).speed == 2) { id(btn_fan2).press(); }
else if (id(mbr_fan).speed == 3) { id(btn_fan3).press(); }
else if (id(mbr_fan).speed == 4) { id(btn_fan4).press(); }
else if (id(mbr_fan).speed == 5) { id(btn_fan5).press(); }
else if (id(mbr_fan).speed == 6) { id(btn_fan6).press(); }
button:
- platform: output
id: btn_light
internal: False
output: light_out
duration: 250ms
- platform: output
id: btn_reverse
name: Switch Direction
internal: False
output: reverse_out
duration: 250ms
- platform: output
id: btn_fan1
internal: True
output: fan1_out
duration: 250ms
- platform: output
id: btn_fan2
internal: True
output: fan2_out
duration: 250ms
- platform: output
id: btn_fan3
internal: True
output: fan3_out
duration: 250ms
- platform: output
id: btn_fan4
internal: True
output: fan4_out
duration: 250ms
- platform: output
id: btn_fan5
internal: True
output: fan5_out
duration: 250ms
- platform: output
id: btn_fan6
internal: True
output: fan6_out
duration: 250ms
- platform: output
id: btn_fan0
internal: True
output: fan0_out
duration: 250ms
script:
- id: check_light_sync
mode: single
then:
- if:
condition:
switch.is_on: light_toggle
then:
if:
condition:
- lambda: 'return id(light).state < 5;'
then:
- button.press: btn_light
- logger.log: "The light was off, turning ON"
- delay: 2s
else:
- logger.log: "The light was already ON"
- delay: 2s
else:
if:
condition:
- lambda: 'return id(light).state > 5;'
then:
- button.press: btn_light
- logger.log: "The light was on, turning OFF"
- delay: 2s
else:
- logger.log: "The light was already OFF"
- delay: 2s
Hi Ryan, do you have any guide on how to use URH to find the signal modulation? I think I have the same remote type or similar you do by the way. If I hold down the light button it allows me to dim the light on the fan.
Hello @implicit_none , im a complete newbie.
I have 3 hampton bay fans, can you share your esphome with me plesse?
i only see a partial code on this thread.
thanks
Miguel
I tried the below and the fan goes on and off but the speeds are not working. I have posted directly to @owenb321 on Github. Will update this thread – If I get the answer.
- fan:
name: "Family Room Fan"
state_topic: "home/hamptonbay/1101/on/state"
command_topic: "home/hamptonbay/1101/on/set"
percentage_state_topic: "home/hamptonbay/1101/percent"
percentage_command_topic: "home/hamptonbay/1101/percent"
preset_mode_state_topic: "home/hamptonbay/1101/speed"
preset_mode_command_topic: "home/hamptonbay/1101/speed"
preset_modes:
- low
- medium
- high
mqtt:
- fan:
name: "Kim Fan"
state_topic: "home/hamptonbay/1010/on/state"
command_topic: "home/hamptonbay/1010/on/set"
preset_mode_command_topic: "home/hamptonbay/1010/speed/state"
preset_mode_command_template: "home/hamptonbay/1010/speed/set"
preset_modes:
- low
- medium
- high
@implicit_none is your esp code complete? Thanks for any help you can give.
I get the error
# https://github.com/dbuezas/esphome-cc1101
esphome:
name: esp-kim-fan
friendly_name: esp-kim-fan
includes:
- cc1101.h
libraries:
- SPI
- "SmartRC-CC1101-Driver-Lib"
esp8266:
board: d1_mini
#esp32:
# board: esp32dev
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
power_save_mode: HIGH
logger:
level: VERBOSE
api:
encryption:
key: "gp2Xhidden"
services:
- service: transmit
variables:
command: string
device: string
then:
- logger.log: "running script"
- script.execute:
id: transmit
device: !lambda return device;
command: !lambda return command;
script:
- id: transmit
mode: queued
parameters:
command: string
device: string
then:
- if:
condition:
lambda: 'return ( device.substr(device.size() - 3) == "fan" );'
then:
- lambda: get_cc1101(transceiver).setFreq(304.25);
- lambda: get_cc1101(transceiver).beginTransmission();
- remote_transmitter.transmit_rc_switch_raw:
repeat:
times: 8
wait_time: 0ms
code: !lambda |-
std::map<std::string, std::string> devices, commands;
devices["room1_fan"] = "0110";
devices["room2_fan"] = "1100";
devices["room3_fan"] = "0111";
devices["room4_fan"] = "0000";
devices["room5_fan"] = "1111";
commands["fan_high"] = "11111110";
commands["fan_medium"] = "11111101";
commands["fan_low"] = "11111100";
commands["fan_off"] = "11111111";
commands["off"] = "01100100";
commands["on"] = "01100101";
commands["light_toggle"] = "11100100";
return ( "1000000000000" + id(devices[device]) + id(commands[command]) );
protocol:
pulse_length: 375
sync: [0,0]
zero: [2,1]
one: [1,2]
inverted: True
- lambda: get_cc1101(transceiver).endTransmission();
# Code breakdown:
# - 13-bit preamble + 4-bit dip settings + 8-bit command
# - preamble: 1000000000000 (1x "1"-bit + 12x "0"-bits)
# - dip settings - as seen in the remote - NOT inverted NOT reversed
# - 8-bit commands:
# - power on (light on, fan high): 01100101
# - power off (light off, fan off): 01100100;
# - toggle light: 11100100
# - fan high: 11111110
# - fan medium 11111101
# - fan low 11111100
# - fan off 11111111;
My journey with this project.
I was intrigued by this project that @owenb321 started. I purchased the transmitters from Ali Express in May of 2023 and just got to starting it off this month. This topic has since evolved and I was estatic to see that I could put this into Esp Home. However the requirements were more and needed a tuner. So I set out and bought a tuner. Then there was the journey on how to learn what was being transmitted. I managed to get rtl_433 going in Virtual Box and I managed to decode high to being the below and same. However I did not know what the protocol was and how many repeats. But I thought I would keep going
[00] {22} 8a 00 98 : 10001010 00000000 100110
Then I started to use @implicit_none code and changed the frequency etc however that did not work for me and I got an error.
At this point having invested days into this project I tried @owenb321 project and figured out how to use Arduino. There was instant sucess! I could turn the fan on and the light on, control two FAN-9T’s however the speed wasn’t working and the MQTT was giving me an error. Long story short @owenb321 was amazing and he fixed the code. So what works? If you are newbie and have FAN-9T remotes then here are the simple steps.
# Example using percentage based speeds with preset modes configuration.yaml
mqtt:
- fan:
name: "Family Room Fan"
state_topic: "home/hamptonbay/1101/on/state"
command_topic: "home/hamptonbay/1101/on/set"
percentage_state_topic: "home/hamptonbay/1101/speed/state"
percentage_value_template: >-
{% if value == 'off' -%}
0
{% elif value == 'low' -%}
1
{%- elif value == 'medium' -%}
2
{%- else -%}
3
{%- endif %}
percentage_command_topic: "home/hamptonbay/1101/speed/set"
percentage_command_template: >-
{% if value | int(default=0) == 0 -%}
off
{%- elif value | int(default=0) == 1 -%}
low
{%- elif value | int(default=0) == 2 -%}
medium
{%- else -%}
high
{%- endif %}
speed_range_max: 3
- fan:
name: "Kim Room Fan"
state_topic: "home/hamptonbay/1010/on/state"
command_topic: "home/hamptonbay/1010/on/set"
percentage_state_topic: "home/hamptonbay/1010/speed/state"
percentage_value_template: >-
{% if value == 'off' -%}
0
{% elif value == 'low' -%}
1
{%- elif value == 'medium' -%}
2
{%- else -%}
3
{%- endif %}
percentage_command_topic: "home/hamptonbay/1010/speed/set"
percentage_command_template: >-
{% if value | int(default=0) == 0 -%}
off
{%- elif value | int(default=0) == 1 -%}
low
{%- elif value | int(default=0) == 2 -%}
medium
{%- else -%}
high
{%- endif %}
speed_range_max: 3
- light:
name: "Kim Fan Light"
command_topic: "home/hamptonbay/1010/light/state"
state_topic: "home/hamptonbay/1010/light/set"
You should be good to go. If this post gets updated with a usable configuration in esp home then I will update. Hope this helps someone.