[esp32_ble_tracker] Use register_apply_action for start_scan and stop_scan (#19520)

This commit is contained in:
J. Nick Koston
2026-09-23 23:25:04 +01:00
committed by GitHub
parent 6a97172867
commit 22efbd9778
3 changed files with 12 additions and 58 deletions
@@ -39,8 +39,7 @@ from esphome.const import (
CONF_SERVICE_UUID,
CONF_TRIGGER_ID,
)
from esphome.core import CORE, ID, CoroPriority, TimePeriod, coroutine_with_priority
from esphome.cpp_generator import MockObj, TemplateArgsType
from esphome.core import CORE, CoroPriority, TimePeriod, coroutine_with_priority
from esphome.enum import StrEnum
from esphome.types import ConfigType
@@ -116,12 +115,6 @@ BLEEndOfScanTrigger = esp32_ble_tracker_ns.class_(
"BLEEndOfScanTrigger", automation.Trigger.template()
)
# Actions
ESP32BLEStartScanAction = esp32_ble_tracker_ns.class_(
"ESP32BLEStartScanAction", automation.Action
)
ESP32BLEStopScanAction = esp32_ble_tracker_ns.class_(
"ESP32BLEStopScanAction", automation.Action
)
def validate_max_connections_deprecated(config: ConfigType) -> ConfigType:
@@ -469,23 +462,12 @@ ESP32_BLE_START_SCAN_ACTION_SCHEMA = cv.Schema(
)
@automation.register_action(
automation.register_apply_action(
"esp32_ble_tracker.start_scan",
ESP32BLEStartScanAction,
ESP32_BLE_START_SCAN_ACTION_SCHEMA,
synchronous=True,
automation.ApplyField(CONF_CONTINUOUS, "set_scan_continuous", cg.bool_),
automation.ApplyCall("start_scan_if_idle()"),
)
async def esp32_ble_tracker_start_scan_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(config[CONF_CONTINUOUS], args, cg.bool_)
cg.add(var.set_continuous(template_))
return var
ESP32_BLE_STOP_SCAN_ACTION_SCHEMA = automation.maybe_simple_id(
@@ -497,21 +479,11 @@ ESP32_BLE_STOP_SCAN_ACTION_SCHEMA = automation.maybe_simple_id(
)
@automation.register_action(
automation.register_apply_action(
"esp32_ble_tracker.stop_scan",
ESP32BLEStopScanAction,
ESP32_BLE_STOP_SCAN_ACTION_SCHEMA,
synchronous=True,
automation.ApplyCall("stop_scan()"),
)
async def esp32_ble_tracker_stop_scan_action_to_code(
config: ConfigType,
action_id: ID,
template_arg: cg.TemplateArguments,
args: TemplateArgsType,
) -> MockObj:
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
async def register_ble_device(
@@ -94,30 +94,6 @@ class BLEEndOfScanTrigger final : public Trigger<>, public ESPBTDeviceListener {
void on_scan_end() override { this->trigger(); }
};
template<typename... Ts> class ESP32BLEStartScanAction final : public Action<Ts...> {
public:
ESP32BLEStartScanAction(ESP32BLETracker *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(bool, continuous)
void play(const Ts &...x) override {
this->parent_->set_scan_continuous(this->continuous_.value(x...));
// Only call start_scan() if scanner is IDLE
// For other states (STARTING, RUNNING, STOPPING, FAILED), the normal state
// machine flow will eventually transition back to IDLE, at which point
// loop() will see scan_continuous_ and restart scanning if it is true.
if (this->parent_->get_scanner_state() == ScannerState::IDLE) {
this->parent_->start_scan();
}
}
protected:
ESP32BLETracker *parent_;
};
template<typename... Ts> class ESP32BLEStopScanAction final : public Action<Ts...>, public Parented<ESP32BLETracker> {
public:
void play(const Ts &...x) override { this->parent_->stop_scan(); }
};
} // namespace esphome::esp32_ble_tracker
#endif
@@ -218,6 +218,12 @@ class ESP32BLETracker final : public Component,
#endif
void start_scan();
// For the start_scan action: in any other state the state machine returns to IDLE on its own
// and loop() restarts scanning when scan_continuous_ is set, so only an idle scanner starts here.
void start_scan_if_idle() {
if (this->scanner_state_ == ScannerState::IDLE)
this->start_scan();
}
void stop_scan();
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);