diff --git a/esphome/components/esp32_ble_server/ble_server_automations.cpp b/esphome/components/esp32_ble_server/ble_server_automations.cpp index 0761de994a..74cf56a765 100644 --- a/esphome/components/esp32_ble_server/ble_server_automations.cpp +++ b/esphome/components/esp32_ble_server/ble_server_automations.cpp @@ -15,7 +15,10 @@ Trigger, uint16_t> *BLETriggers::create_characteristic_on_w Trigger, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory) new Trigger, uint16_t>(); characteristic->on_write([on_write_trigger](std::span data, uint16_t id) { - // Convert span to vector for trigger + // Convert span to vector for trigger - copy is necessary because: + // 1. Trigger stores the data for use in automation actions that execute later + // 2. The span is only valid during this callback (points to temporary BLE stack data) + // 3. User lambdas in automations need persistent data they can access asynchronously on_write_trigger->trigger(std::vector(data.begin(), data.end()), id); }); return on_write_trigger; @@ -27,7 +30,10 @@ Trigger, uint16_t> *BLETriggers::create_descriptor_on_write Trigger, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory) new Trigger, uint16_t>(); descriptor->on_write([on_write_trigger](std::span data, uint16_t id) { - // Convert span to vector for trigger + // Convert span to vector for trigger - copy is necessary because: + // 1. Trigger stores the data for use in automation actions that execute later + // 2. The span is only valid during this callback (points to temporary BLE stack data) + // 3. User lambdas in automations need persistent data they can access asynchronously on_write_trigger->trigger(std::vector(data.begin(), data.end()), id); }); return on_write_trigger;