mirror of
https://github.com/athom-tech/esp32-configs.git
synced 2026-10-26 22:10:21 +00:00
Add RF433 radio frequency learning function
This commit is contained in:
1 parent
1e158ae7e4
commit
a512f91473
1 file changed
+146
-2
+146
-2
@@ -10,7 +10,7 @@ substitutions:
|
||||
# Project Name
|
||||
project_name: "China Athom Technology.Athom RF IR Remote"
|
||||
# Projection version denotes the release version of the yaml file, allowing checking of deployed vs latest version
|
||||
project_version: "v3.0.4"
|
||||
project_version: "v3.0.5"
|
||||
# Define a domain for this device to use. i.e. iot.home.lan (so device will appear as athom-smart-plug-v2.iot.home.lan in DNS/DHCP logs)
|
||||
dns_domain: ".local"
|
||||
# Set timezone of the smart plug. Useful if the plug is in a location different to the HA server. Can be entered in unix Country/Area format (i.e. "Australia/Sydney")
|
||||
@@ -84,6 +84,26 @@ globals:
|
||||
type: int
|
||||
restore_value: no
|
||||
initial_value: '10'
|
||||
# RF433 learning mode flag (independent from IR learning)
|
||||
- id: is_rf_learning_mode
|
||||
type: bool
|
||||
restore_value: no
|
||||
initial_value: 'false'
|
||||
# RF433 slot index, offset to 10-19 so it never collides with IR slots 0-9
|
||||
- id: rf_signal_select_index
|
||||
type: int
|
||||
restore_value: yes
|
||||
initial_value: '10'
|
||||
# Temp holders for the rc_switch code/protocol to transmit; referenced by
|
||||
# transmit_rc_switch_raw's !lambda during playback
|
||||
- id: rf_tx_code
|
||||
type: uint64_t
|
||||
restore_value: no
|
||||
initial_value: '0'
|
||||
- id: rf_tx_protocol
|
||||
type: int
|
||||
restore_value: no
|
||||
initial_value: '0'
|
||||
|
||||
# Flash storage component for saving IR signals
|
||||
Flash_comp:
|
||||
@@ -178,8 +198,26 @@ remote_receiver:
|
||||
number: ${RF_RX_PIN}
|
||||
inverted: true
|
||||
dump: rc_switch
|
||||
tolerance: 25%
|
||||
# RF433 fixed-code decoding: filter glitches, split frames on 4ms idle,
|
||||
# and widen tolerance for cheap remotes. rc_switch decoding rejects the
|
||||
# receiver's ambient noise, so learning no longer false-triggers.
|
||||
filter: 4us
|
||||
idle: 4ms
|
||||
tolerance: 50%
|
||||
id: rf_receiver
|
||||
on_rc_switch:
|
||||
- lambda: |-
|
||||
if (id(is_rf_learning_mode)) {
|
||||
std::vector<int> d;
|
||||
d.push_back((int) x.protocol);
|
||||
d.push_back((int) (x.code >> 32));
|
||||
d.push_back((int) (x.code & 0xFFFFFFFF));
|
||||
id(signal_nvs).save_to_nvs(id(rf_signal_select_index), d);
|
||||
ESP_LOGI("RF_LEARNING", "Learned protocol=%u code=%llu slot=%d",
|
||||
x.protocol, (unsigned long long) x.code, id(rf_signal_select_index));
|
||||
id(is_rf_learning_mode) = false;
|
||||
id(rf_status_text).publish_state("Signal learned!");
|
||||
}
|
||||
|
||||
- pin:
|
||||
number: ${IR_RX_PIN}
|
||||
@@ -335,6 +373,34 @@ button:
|
||||
ESP_LOGI("IR_LEARNING", "Cleared slot %d", id(signal_select_index));
|
||||
id(status_text).publish_state("Slot cleared");
|
||||
|
||||
# RF433 learning button
|
||||
- platform: template
|
||||
name: "RF Learn"
|
||||
icon: mdi:remote
|
||||
on_press:
|
||||
- lambda: |-
|
||||
id(is_rf_learning_mode) = true;
|
||||
ESP_LOGI("RF_LEARNING", "Learning mode activated for slot %d", id(rf_signal_select_index));
|
||||
id(rf_status_text).publish_state("Ready to learn...");
|
||||
|
||||
# RF433 send button
|
||||
- platform: template
|
||||
name: "RF Send"
|
||||
icon: mdi:send
|
||||
on_press:
|
||||
- script.execute: send_raw_rf_signal
|
||||
|
||||
# Clear the RF signal in the current slot
|
||||
- platform: template
|
||||
name: "RF Clear Slot"
|
||||
icon: mdi:delete
|
||||
on_press:
|
||||
- lambda: |-
|
||||
std::vector<int> empty_signal;
|
||||
id(signal_nvs).save_to_nvs(id(rf_signal_select_index), empty_signal);
|
||||
ESP_LOGI("RF_LEARNING", "Cleared slot %d", id(rf_signal_select_index));
|
||||
id(rf_status_text).publish_state("Slot cleared");
|
||||
|
||||
light:
|
||||
- platform: status_led
|
||||
name: "Status LED"
|
||||
@@ -368,6 +434,12 @@ text_sensor:
|
||||
id: status_text
|
||||
icon: mdi:information
|
||||
|
||||
# RF433 learning status display
|
||||
- platform: template
|
||||
name: "RF Learning Status"
|
||||
id: rf_status_text
|
||||
icon: mdi:information
|
||||
|
||||
# Signal slot selector
|
||||
select:
|
||||
- platform: template
|
||||
@@ -400,6 +472,37 @@ select:
|
||||
else if (x == "Signal 9") id(signal_select_index) = 9;
|
||||
ESP_LOGI("IR_LEARNING", "Selected slot: %d", id(signal_select_index));
|
||||
|
||||
# RF433 signal slot selector (mapped to NVS index 10-19 to avoid IR collision)
|
||||
- platform: template
|
||||
name: "RF Signal Slot"
|
||||
id: rf_signal_slot_select
|
||||
optimistic: true
|
||||
options:
|
||||
- "Signal 0"
|
||||
- "Signal 1"
|
||||
- "Signal 2"
|
||||
- "Signal 3"
|
||||
- "Signal 4"
|
||||
- "Signal 5"
|
||||
- "Signal 6"
|
||||
- "Signal 7"
|
||||
- "Signal 8"
|
||||
- "Signal 9"
|
||||
initial_option: "Signal 0"
|
||||
on_value:
|
||||
- lambda: |-
|
||||
if (x == "Signal 0") id(rf_signal_select_index) = 10;
|
||||
else if (x == "Signal 1") id(rf_signal_select_index) = 11;
|
||||
else if (x == "Signal 2") id(rf_signal_select_index) = 12;
|
||||
else if (x == "Signal 3") id(rf_signal_select_index) = 13;
|
||||
else if (x == "Signal 4") id(rf_signal_select_index) = 14;
|
||||
else if (x == "Signal 5") id(rf_signal_select_index) = 15;
|
||||
else if (x == "Signal 6") id(rf_signal_select_index) = 16;
|
||||
else if (x == "Signal 7") id(rf_signal_select_index) = 17;
|
||||
else if (x == "Signal 8") id(rf_signal_select_index) = 18;
|
||||
else if (x == "Signal 9") id(rf_signal_select_index) = 19;
|
||||
ESP_LOGI("RF_LEARNING", "Selected slot: %d", id(rf_signal_select_index));
|
||||
|
||||
# Script for sending raw IR signals
|
||||
script:
|
||||
- id: send_raw_signal
|
||||
@@ -426,6 +529,47 @@ script:
|
||||
id(status_text).publish_state("No signal in this slot");
|
||||
}
|
||||
|
||||
# Script for sending learned RF433 rc_switch signals
|
||||
- id: send_raw_rf_signal
|
||||
then:
|
||||
# Load [protocol, code_high, code_low] from NVS and rebuild the 64-bit code
|
||||
# into the temp globals that transmit_rc_switch_raw reads via !lambda.
|
||||
- lambda: |-
|
||||
std::vector<int> d = id(signal_nvs).load_from_nvs<int>(id(rf_signal_select_index));
|
||||
if (d.size() >= 3) {
|
||||
id(rf_tx_protocol) = d[0];
|
||||
id(rf_tx_code) = ((uint64_t) (uint32_t) d[1] << 32) | (uint32_t) d[2];
|
||||
ESP_LOGI("RF_SEND", "Sending protocol=%d code=%llu slot=%d",
|
||||
id(rf_tx_protocol), (unsigned long long) id(rf_tx_code), id(rf_signal_select_index));
|
||||
id(rf_status_text).publish_state("Sending signal...");
|
||||
} else {
|
||||
id(rf_tx_protocol) = 0;
|
||||
ESP_LOGW("RF_SEND", "No signal stored in slot %d", id(rf_signal_select_index));
|
||||
id(rf_status_text).publish_state("No signal in this slot");
|
||||
}
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(rf_tx_protocol) > 0;'
|
||||
then:
|
||||
- remote_transmitter.transmit_rc_switch_raw:
|
||||
# protocol must be an RCSwitchBase: index the built-in table (1..8)
|
||||
protocol: !lambda 'return esphome::remote_base::RC_SWITCH_PROTOCOLS[id(rf_tx_protocol)];'
|
||||
# code must be an MSB-first binary string; its length is the bit count.
|
||||
# on_rc_switch does not expose the received bit length, and virtually
|
||||
# all 433MHz fixed-code remotes (EV1527/PT2262/…) are 24-bit.
|
||||
code: !lambda |-
|
||||
uint64_t code = id(rf_tx_code);
|
||||
const int nbits = 24;
|
||||
std::string s;
|
||||
for (int i = nbits - 1; i >= 0; i--)
|
||||
s += (code & ((uint64_t) 1 << i)) ? '1' : '0';
|
||||
return s;
|
||||
transmitter_id: rf_transmitter
|
||||
repeat:
|
||||
times: 5
|
||||
wait_time: 0us
|
||||
- lambda: 'id(rf_status_text).publish_state("Signal sent!");'
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: sntp_time
|
||||
|
||||
Reference in new issue
Block a user