diff --git a/.github/test-config.yaml b/.github/test-config.yaml
index 12bd998..908e8ea 100644
--- a/.github/test-config.yaml
+++ b/.github/test-config.yaml
@@ -79,8 +79,6 @@ lock:
 
     led_brightness:
       name: "Nuki LED Brightness"
-    security_pin:
-      name: "Nuki Security Pin"
     timezone_offset:
       name: "Nuki Timezone: Offset"
 
@@ -101,6 +99,7 @@ lock:
 
     pairing_mode_timeout: 300s
     event: "nuki"
+    security_pin: 1234
 
     on_pairing_mode_on_action:
       - lambda: ESP_LOGI("nuki_lock", "Pairing mode turned on");
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 88f4659..c93f672 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -11,9 +11,9 @@
       runs-on: ubuntu-latest
       steps:
         - name: Checkout
-          uses: actions/checkout@v3
+          uses: actions/checkout@v4
 
         - name: Compile Firmware
-          uses: esphome/build-action@v4.0.1
+          uses: esphome/build-action@v5.0.0
           with:
             yaml-file: .github/test-config.yaml
\ No newline at end of file
diff --git a/README.md b/README.md
index 058ac00..4ac7912 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ lock:
   # Optional: Settings
     pairing_mode_timeout: 300s
     event: "nuki"
+    security_pin: 1234
   # Optional: Binary Sensors
     is_connected:
       name: "Nuki Connected"
@@ -59,8 +60,6 @@ lock:
     led_enabled:
       name: "Nuki LED Signal"
   # Optional: Number Inputs
-    security_pin:
-      name: "Nuki Security Pin"
     led_brightness:
       name: "Nuki LED Brightness"
     timezone_offset:
@@ -197,6 +196,19 @@ on_...:
   - nuki_lock.unpair:
 ```
 
+### Action: Security Pin
+
+> [!IMPORTANT]  
+> Overriding the security PIN will save it to flash!  
+> To revert back to the PIN defined in your YAML configuration, you must set the override PIN to `0`.
+
+To override the security pin without recompiling, use the following action:
+```yaml
+on_...:
+  - nuki_lock.set_security_pin:
+      security_pin: 1234
+```
+
 ### Callbacks
 To run specific actions when certain events occur, you can use the following callbacks:
 ```yaml
@@ -209,14 +221,18 @@ on_paired_action:
 ```
 
 ### Events
-By default, this component sends Nuki logs as events to Home Assistant, enabling you to use them in automations. 
+By default, this component sends Nuki logs as events to Home Assistant, enabling you to use them in automations.
+
+> [!IMPORTANT]
+> To receive events, **you must set your security PIN**.
+> Without it, it's not possible to access any event logs from your lock.
 
 - **To Disable Logs**: Set the `event` property in your YAML configuration to `none` if you don't want to receive log events.
   
 - **To View Log Events**: Go to **Home Assistant Developer Tools** -> **Events**, and listen for `esphome.nuki` events to monitor log activity.
 
-These log events provide insights into lock operations and help fine-tune automations based on real-time lock data.
-
+These log events provide insights into lock operations and help fine-tune automations based on lock data.
+Keep in mind that the logs **are not displayed in real-time** and may take up to a minute to arrive.
 
 Example Event:
 ```yaml
@@ -246,6 +262,11 @@ context:
 
 ## Entities
 
+> [!IMPORTANT]  
+> Most settings entities **require the security PIN** to make changes.  
+> Without the PIN, modifying these settings is not possible.  
+> Additionally, the `Last Unlock User` feature will only function if events are enabled!  
+
 **Lock:**  
 - Lock
 
@@ -291,7 +312,6 @@ context:
 **Number Input:**  
 - LED Brightness
 - Timezone Offset
-- Security Pin
 
 **Button:**  
 - Unpair Device
diff --git a/components/nuki_lock/lock.py b/components/nuki_lock/lock.py
index 4eddb02..03591a9 100644
--- a/components/nuki_lock/lock.py
+++ b/components/nuki_lock/lock.py
@@ -57,7 +57,7 @@
 CONF_ADVERTISING_MODE_SELECT = "advertising_mode"
 
 CONF_LED_BRIGHTNESS_NUMBER = "led_brightness"
-CONF_SECURITY_PIN_NUMBER = "security_pin"
+CONF_SECURITY_PIN = "security_pin"
 CONF_TIMEZONE_OFFSET_NUMBER = "timezone_offset"
 
 CONF_BUTTON_PRESS_ACTION_SELECT_OPTIONS = [
@@ -139,6 +139,7 @@
 CONF_EVENT = "event"
 
 CONF_SET_PAIRING_MODE = "pairing_mode"
+CONF_SET_SECURITY_PIN = "security_pin"
 
 CONF_ON_PAIRING_MODE_ON = "on_pairing_mode_on_action"
 CONF_ON_PAIRING_MODE_OFF = "on_pairing_mode_off_action"
@@ -165,7 +166,6 @@
 NukiLockDstModeEnabledSwitch = nuki_lock_ns.class_("NukiLockDstModeEnabledSwitch", switch.Switch, cg.Component)
 
 NukiLockLedBrightnessNumber = nuki_lock_ns.class_("NukiLockLedBrightnessNumber", number.Number, cg.Component)
-NukiLockSecurityPinNumber = nuki_lock_ns.class_("NukiLockSecurityPinNumber", number.Number, cg.Component)
 NukiLockTimeZoneOffsetNumber = nuki_lock_ns.class_("NukiLockTimeZoneOffsetNumber", number.Number, cg.Component)
 
 NukiLockSingleButtonPressActionSelect = nuki_lock_ns.class_("NukiLockSingleButtonPressActionSelect", select.Select, cg.Component)
@@ -184,6 +184,10 @@
     "NukiLockPairingModeAction", automation.Action
 )
 
+NukiLockSecurityPinAction = nuki_lock_ns.class_(
+    "NukiLockSecurityPinAction", automation.Action
+)
+
 PairingModeOnTrigger = nuki_lock_ns.class_("PairingModeOnTrigger", automation.Trigger.template())
 PairingModeOffTrigger = nuki_lock_ns.class_("PairingModeOffTrigger", automation.Trigger.template())
 PairedTrigger = nuki_lock_ns.class_("PairedTrigger", automation.Trigger.template())
@@ -329,11 +333,7 @@
         entity_category=ENTITY_CATEGORY_CONFIG,
         icon="mdi:brightness-6",
     ),
-    cv.Optional(CONF_SECURITY_PIN_NUMBER): number.number_schema(
-        NukiLockSecurityPinNumber,
-        entity_category=ENTITY_CATEGORY_CONFIG,
-        icon="mdi:shield-key",
-    ).extend({ cv.Optional(CONF_MODE, default="BOX"): cv.enum(NUMBER_MODES, upper=True), }),
+
     cv.Optional(CONF_TIMEZONE_OFFSET_NUMBER): number.number_schema(
         NukiLockTimeZoneOffsetNumber,
         entity_category=ENTITY_CATEGORY_CONFIG,
@@ -378,6 +378,7 @@
 
     cv.Optional(CONF_PAIRING_MODE_TIMEOUT, default="300s"): cv.positive_time_period_seconds,
     cv.Optional(CONF_EVENT, default="nuki"): cv.string,
+    cv.Optional(CONF_SECURITY_PIN): cv.uint16_t,
 
     cv.Optional(CONF_ON_PAIRING_MODE_ON): automation.validate_automation(
         {
@@ -408,6 +409,9 @@ async def to_code(config):
 
     if CONF_EVENT in config:
         cg.add(var.set_event("esphome." + config[CONF_EVENT]))
+        
+    if CONF_SECURITY_PIN in config:
+        cg.add(var.set_security_pin(config[CONF_SECURITY_PIN]))
 
     # Binary Sensor
     if is_connected := config.get(CONF_IS_CONNECTED):
@@ -462,13 +466,6 @@ async def to_code(config):
         await cg.register_parented(n, config[CONF_ID])
         cg.add(var.set_led_brightness_number(n))
 
-    if security_pin := config.get(CONF_SECURITY_PIN_NUMBER):
-        n = await number.new_number(
-            security_pin, min_value=0, max_value=65535, step=1
-        )
-        await cg.register_parented(n, config[CONF_ID])
-        cg.add(var.set_security_pin_number(n))
-
     if timezone_offset := config.get(CONF_TIMEZONE_OFFSET_NUMBER):
         n = await number.new_number(
             timezone_offset, min_value=-60, max_value=60, step=1
@@ -620,14 +617,16 @@ async def to_code(config):
 
     # Libraries
     cg.add_library("Preferences", None)
-    cg.add_library("h2zero/NimBLE-Arduino", "1.4.0")
+    cg.add_library("h2zero/NimBLE-Arduino", "1.4.2")
     cg.add_library("Crc16", None)
     cg.add_library(
         None,
         None,
-        "https://github.com/I-Connect/NukiBleEsp32#93e7da927171c8973b7ef857c7fa644c174ed47d",
+        "https://github.com/I-Connect/NukiBleEsp32#940d809",
     )
 
+    cg.add_define("NUKI_ALT_CONNECT")
+
 
 # Actions
 NukiLockUnpairAction = nuki_lock_ns.class_(
@@ -666,4 +665,25 @@ async def nuki_lock_set_pairing_mode_to_code(config, action_id, template_arg, ar
     var = cg.new_Pvariable(action_id, template_arg, paren)
     pairing_mode_template_ = await cg.templatable(config[CONF_SET_PAIRING_MODE], args, cg.bool_)
     cg.add(var.set_pairing_mode(pairing_mode_template_))
+    return var
+
+
+
+
+NUKI_LOCK_SET_SECURITY_PIN_SCHEMA = automation.maybe_simple_id(
+    {
+        cv.GenerateID(): cv.use_id(NukiLock),
+        cv.Required(CONF_SET_SECURITY_PIN): cv.templatable(cv.uint16_t)
+    }
+)
+
+@automation.register_action(
+    "nuki_lock.set_security_pin", NukiLockSecurityPinAction, NUKI_LOCK_SET_SECURITY_PIN_SCHEMA
+)
+
+async def nuki_lock_set_security_pin_to_code(config, action_id, template_arg, args):
+    paren = await cg.get_variable(config[CONF_ID])
+    var = cg.new_Pvariable(action_id, template_arg, paren)
+    security_pin_template_ = await cg.templatable(config[CONF_SET_SECURITY_PIN], args, cg.uint16)
+    cg.add(var.set_security_pin(security_pin_template_))
     return var
\ No newline at end of file
diff --git a/components/nuki_lock/nuki_lock.cpp b/components/nuki_lock/nuki_lock.cpp
index f832eef..fb2ef74 100644
--- a/components/nuki_lock/nuki_lock.cpp
+++ b/components/nuki_lock/nuki_lock.cpp
@@ -263,16 +263,18 @@ void NukiLockComponent::update_status()
 
     if (cmd_result == Nuki::CmdResult::Success) {
         this->status_update_consecutive_errors_ = 0;
-        NukiLock::LockState current_lock_state = this->retrieved_key_turner_state_.lockState;
 
+        NukiLock::LockState current_lock_state = this->retrieved_key_turner_state_.lockState;
         char current_lock_state_as_string[30];
         NukiLock::lockstateToString(current_lock_state, current_lock_state_as_string);
 
-        char last_lock_action[30];
-        NukiLock::lockactionToString(this->retrieved_key_turner_state_.lastLockAction, last_lock_action);
+        NukiLock::LockAction last_lock_action = this->retrieved_key_turner_state_.lastLockAction;
+        char last_lock_action_str[30];
+        NukiLock::lockactionToString(last_lock_action, last_lock_action_str);
 
-        char last_lock_action_trigger[30];
-        NukiLock::triggerToString(this->retrieved_key_turner_state_.lastLockActionTrigger, last_lock_action_trigger);
+        NukiLock::Trigger last_lock_action_trigger = this->retrieved_key_turner_state_.lastLockActionTrigger;
+        char last_lock_action_trigger_str[30];
+        NukiLock::triggerToString(last_lock_action_trigger, last_lock_action_trigger_str);
 
         ESP_LOGI(TAG, "Bat state: %#x, Bat crit: %d, Bat perc: %d lock state: %s (%d) %d:%d:%d",
             this->retrieved_key_turner_state_.criticalBatteryState,
@@ -303,9 +305,9 @@ void NukiLockComponent::update_status()
         if (this->door_sensor_state_text_sensor_ != nullptr)
             this->door_sensor_state_text_sensor_->publish_state(this->nuki_doorsensor_to_string(this->retrieved_key_turner_state_.doorSensorState));
         if (this->last_lock_action_text_sensor_ != nullptr)
-            this->last_lock_action_text_sensor_->publish_state(last_lock_action);
+            this->last_lock_action_text_sensor_->publish_state(last_lock_action_str);
         if (this->last_lock_action_trigger_text_sensor_ != nullptr)
-            this->last_lock_action_trigger_text_sensor_->publish_state(last_lock_action_trigger);
+            this->last_lock_action_trigger_text_sensor_->publish_state(last_lock_action_trigger_str);
         #endif
 
         if (
@@ -315,7 +317,10 @@ void NukiLockComponent::update_status()
             // Schedule a status update without waiting for the next advertisement because the lock
             // is in a transition state. This will speed up the feedback.
             this->status_update_ = true;
-            this->event_log_update_ = true;
+            
+            if (strcmp(event_, "esphome.none") != 0) {
+                this->event_log_update_ = true;
+            }
         }
     } else {
         ESP_LOGE(TAG, "requestKeyTurnerState failed with error %s (%d)", cmd_result_as_string, cmd_result);
@@ -433,104 +438,99 @@ void NukiLockComponent::update_advanced_config() {
     }
 }
 
-void NukiLockComponent::update_auth_data()
-{
+void NukiLockComponent::update_auth_data() {
     this->auth_data_update_ = false;
+    this->cancel_timeout("wait_for_auth_data");
 
-    Nuki::CmdResult conf_req_result = (Nuki::CmdResult)-1;
-    int retryCount = 0;
-    while(retryCount < 3)
-    {
-        ESP_LOGD(TAG, "Retrieve Auth Data");
-        conf_req_result = this->nuki_lock_.retrieveAuthorizationEntries(0, MAX_AUTH_DATA_ENTRIES);
+    ESP_LOGD(TAG, "Retrieve Auth Data");
 
-        if(conf_req_result != Nuki::CmdResult::Success)
-        {
-            ++retryCount;
-            App.feed_wdt();
-        }
-        else
-        {
-            break;
-        }
-    }
-
-    this->set_timeout("wait_for_auth_data", 5000, [this]() {
-        std::list<NukiLock::AuthorizationEntry> authEntries;
-        this->nuki_lock_.getAuthorizationEntries(&authEntries);
-
-        authEntries.sort([](const NukiLock::AuthorizationEntry& a, const NukiLock::AuthorizationEntry& b)
-        {
-            return a.authId < b.authId;
-        });
+    Nuki::CmdResult auth_data_req_result = this->nuki_lock_.retrieveAuthorizationEntries(0, MAX_AUTH_DATA_ENTRIES);
+    char auth_data_req_result_as_string[30];
+    NukiLock::cmdResultToString(auth_data_req_result, auth_data_req_result_as_string);
 
-        if(authEntries.size() > MAX_AUTH_DATA_ENTRIES)
-        {
-            authEntries.resize(MAX_AUTH_DATA_ENTRIES);
-        }
+    if (auth_data_req_result == Nuki::CmdResult::Success) {
+        ESP_LOGD(TAG, "retrieveAuthorizationEntries has resulted in %s (%d)", auth_data_req_result_as_string, auth_data_req_result);
+    
+        this->set_timeout("wait_for_auth_data", 5000, [this]() {
 
-        for(const auto& entry : authEntries)
-        {
-            ESP_LOGD(TAG, "Authorization entry[%d] type: %d name: %s", entry.authId, entry.idType, entry.name);
-            this->auth_entries_[entry.authId] = std::string(reinterpret_cast<const char*>(entry.name));
-        }
+            std::list<NukiLock::AuthorizationEntry> authEntries;
+            this->nuki_lock_.getAuthorizationEntries(&authEntries);
+    
+            ESP_LOGD(TAG, "Authorization Entries: %d", authEntries.size());
 
-        // Request Event logs when Auth Data is available
-        this->event_log_update_ = true;
-    });
+            if(authEntries.size() > 0) {
+                authEntries.sort([](const NukiLock::AuthorizationEntry& a, const NukiLock::AuthorizationEntry& b) {
+                    return a.authId < b.authId;
+                });
+        
+                if(authEntries.size() > MAX_AUTH_DATA_ENTRIES) {
+                    authEntries.resize(MAX_AUTH_DATA_ENTRIES);
+                }
+        
+                for(const auto& entry : authEntries) {
+                    ESP_LOGD(TAG, "Authorization entry[%d] type: %d name: %s", entry.authId, entry.idType, entry.name);
+                    this->auth_entries_[entry.authId] = std::string(reinterpret_cast<const char*>(entry.name));
+                }
+        
+                // Request Event logs when Auth Data is available
+                this->event_log_update_ = true;
+            } else {
+                ESP_LOGD(TAG, "No auth entries! Did you set the security pin?");
+            }
+        });
+    } else {
+        ESP_LOGE(TAG, "retrieveAuthorizationEntries has resulted in %s (%d)", auth_data_req_result_as_string, auth_data_req_result);
+        this->auth_data_update_ = true;
+    }
 }
 
-void NukiLockComponent::update_event_logs()
-{
+void NukiLockComponent::update_event_logs() {
     this->event_log_update_ = false;
+    this->cancel_timeout("wait_for_log_entries");
 
-    Nuki::CmdResult conf_req_result = (Nuki::CmdResult)-1;
-    int retryCount = 0;
-    while(retryCount < 3)
-    {
-        ESP_LOGD(TAG, "Retrieve Event Logs");
-        conf_req_result = this->nuki_lock_.retrieveLogEntries(0, MAX_EVENT_LOG_ENTRIES, 1, false);
+    ESP_LOGD(TAG, "Retrieve Event Log Entries");
 
-        if(conf_req_result != Nuki::CmdResult::Success)
-        {
-            ++retryCount;
-            App.feed_wdt();
-        }
-        else
-        {
-            break;
-        }
-    }
+    Nuki::CmdResult event_log_req_result = this->nuki_lock_.retrieveLogEntries(0, MAX_EVENT_LOG_ENTRIES, 1, false);
+    char event_log_req_result_as_string[30];
+    NukiLock::cmdResultToString(event_log_req_result, event_log_req_result_as_string);
 
-    this->set_timeout("wait_for_log_entries", 5000, [this]() {
-        std::list<NukiLock::LogEntry> log;
-        this->nuki_lock_.getLogEntries(&log);
+    if (event_log_req_result == Nuki::CmdResult::Success) {
+        ESP_LOGD(TAG, "retrieveLogEntries has resulted in %s (%d)", event_log_req_result_as_string, event_log_req_result);
+        
+        this->set_timeout("wait_for_log_entries", 5000, [this]() {
+            std::list<NukiLock::LogEntry> log;
+            this->nuki_lock_.getLogEntries(&log);
+    
+            ESP_LOGD(TAG, "Log Entries: %d", log.size());
 
-        if(log.size() > MAX_EVENT_LOG_ENTRIES)
-        {
-            log.resize(MAX_EVENT_LOG_ENTRIES);
-        }
+            if(log.size() > 0) {
+                if(log.size() > MAX_EVENT_LOG_ENTRIES) {
+                    log.resize(MAX_EVENT_LOG_ENTRIES);
+                }
+        
+                log.sort([](const NukiLock::LogEntry& a, const NukiLock::LogEntry& b) {
+                    return a.index < b.index;
+                });
 
-        log.sort([](const NukiLock::LogEntry& a, const NukiLock::LogEntry& b)
-        {
-            return a.index < b.index;
+                this->process_log_entries(log);
+            } else {
+                ESP_LOGD(TAG, "No log entries! Did you set the security pin?");
+            }
         });
-
-        if(log.size() > 0)
-        {
-            this->process_log_entries(log);
-        }
-    });
+    } else {
+        ESP_LOGE(TAG, "retrieveAuthorizationEntries has resulted in %s (%d)", event_log_req_result_as_string, event_log_req_result);
+        this->event_log_update_ = true;
+    }
 }
 
-void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>& log_entries)
-{
+void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>& log_entries) {
+    ESP_LOGD(TAG, "Process Event Log Entries");
+
     char str[50];
     char auth_name[33];
     uint32_t auth_index = 0;
 
-    for(const auto& log : log_entries)
-    {
+    for(const auto& log : log_entries) {
         memset(auth_name, 0, sizeof(auth_name));
         auth_name[0] = '\0';
 
@@ -538,42 +538,38 @@ void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>&
         {
             int sizeName = sizeof(log.name);
             memcpy(auth_name, log.name, sizeName);
-            if(auth_name[sizeName - 1] != '\0')
-            {
+            if(auth_name[sizeName - 1] != '\0') {
                 auth_name[sizeName] = '\0';
             }
 
-            if (std::string(auth_name) == "")
-            {
+            if (std::string(auth_name) == "") {
                 memset(auth_name, 0, sizeof(auth_name));
                 memcpy(auth_name, "Manual", strlen("Manual"));
             }
 
-            if(log.index > auth_index)
-            {
+            if(log.index > auth_index) {
                 auth_index = log.index;
                 this->auth_id_ = log.authId;
 
                 memset(this->auth_name_, 0, sizeof(this->auth_name_));
                 memcpy(this->auth_name_, auth_name, sizeof(auth_name));
 
-                if(auth_name[sizeName - 1] != '\0' && this->auth_entries_.count(this->auth_id_) > 0)
-                {
+                if(auth_name[sizeName - 1] != '\0' && this->auth_entries_.count(this->auth_id_) > 0) {
                     memset(this->auth_name_, 0, sizeof(this->auth_name_));
                     memcpy(this->auth_name_, this->auth_entries_[this->auth_id_].c_str(), sizeof(this->auth_entries_[this->auth_id_].c_str()));
                 }
             }
         }
 
-        if (strcmp(event_, "esphome.none") != 0)
-        {
+        if (strcmp(event_, "esphome.none") != 0) {
+            ESP_LOGD(TAG, "Prepare event data for %s", event_);
+
             std::map<std::string, std::string> event_data;
             event_data["index"] = std::to_string(log.index);
             event_data["authorizationId"] = std::to_string(log.authId);
             event_data["authorizationName"] = this->auth_name_;
 
-            if(this->auth_entries_.count(log.authId) > 0)
-            {
+            if(this->auth_entries_.count(log.authId) > 0) {
                 event_data["authorizationName"] = this->auth_entries_[log.authId];
             }
 
@@ -588,8 +584,7 @@ void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>&
             NukiLock::loggingTypeToString(log.loggingType, str);
             event_data["type"] = str;
 
-            switch(log.loggingType)
-            {
+            switch(log.loggingType) {
                 case NukiLock::LoggingType::LockAction:
                     memset(str, 0, sizeof(str));
                     NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
@@ -609,8 +604,7 @@ void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>&
                     NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
                     event_data["action"] = str;
 
-                    switch(log.data[1])
-                    {
+                    switch(log.data[1]) {
                         case 0:
                             event_data["trigger"] = "arrowkey";
                             break;
@@ -627,16 +621,11 @@ void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>&
 
                     memset(str, 0, sizeof(str));
 
-                    if(log.data[2] == 9)
-                    {
+                    if(log.data[2] == 9) {
                         event_data["trigger"] = "notAuthorized";
-                    }
-                    else if (log.data[2] == 224)
-                    {
+                    } else if (log.data[2] == 224) {
                         event_data["trigger"] = "invalidCode";
-                    }
-                    else
-                    {
+                    } else {
                         NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
                         event_data["completionStatus"] = str;
                     }
@@ -645,8 +634,7 @@ void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>&
                     break;
 
                 case NukiLock::LoggingType::DoorSensor:
-                    switch(log.data[0])
-                    {
+                    switch(log.data[0]) {
                         case 0:
                             event_data["action"] = "DoorOpened";
                             break;
@@ -665,8 +653,7 @@ void NukiLockComponent::process_log_entries(const std::list<NukiLock::LogEntry>&
             
             // Send as Home Assistant Event
             #ifdef USE_API
-            if(log.index > this->last_rolling_log_id)
-            {
+            if(log.index > this->last_rolling_log_id) {
                 this->last_rolling_log_id = log.index;
                 
                 auto capi = new esphome::api::CustomAPIDevice();
@@ -716,21 +703,19 @@ bool NukiLockComponent::execute_lock_action(NukiLock::LockAction lock_action) {
     }
 }
 
-void NukiLockComponent::set_security_pin(uint16_t security_pin)
-{
+void NukiLockComponent::set_override_security_pin(uint16_t security_pin) {
     this->security_pin_ = security_pin;
+    save_settings();
+    use_security_pin();
+}
 
+void NukiLockComponent::use_security_pin() {
     bool result = this->nuki_lock_.saveSecurityPincode(this->security_pin_);
     if (result) {
         ESP_LOGI(TAG, "Set pincode done");
     } else {
         ESP_LOGE(TAG, "Set pincode failed!");
     }
-
-    #ifdef USE_NUMBER
-    if (this->security_pin_number_ != nullptr)
-        this->security_pin_number_->publish_state(this->security_pin_);
-    #endif
 }
 
 void NukiLockComponent::setup() {
@@ -744,11 +729,15 @@ void NukiLockComponent::setup() {
     this->pref_ = global_preferences->make_preference<NukiLockSettings>(global_nuki_lock_id);
 
     NukiLockSettings recovered;
-    if (!this->pref_.load(&recovered))
-    {
+    if (!this->pref_.load(&recovered)) {
         recovered = {0};
     }
-    this->set_security_pin(recovered.security_pin);
+
+    if(recovered.security_pin != 0)
+    {
+        this->security_pin_ = recovered.security_pin;
+    }
+    this->use_security_pin();
 
     this->traits.set_supported_states(
         std::set<lock::LockState> {
@@ -776,8 +765,11 @@ void NukiLockComponent::setup() {
         this->advanced_config_update_ = true;
 
         // First auth data request, then every 2nd time
-        this->auth_data_required_ = true;
-        this->auth_data_update_ = true;
+        // Requesting only when events are enabled
+        if (strcmp(event_, "esphome.none") != 0) {
+            this->auth_data_required_ = true;
+            this->auth_data_update_ = true;
+        }
 
         ESP_LOGI(TAG, "%s Nuki paired", this->deviceName_);
         #ifdef USE_BINARY_SENSOR
@@ -1125,7 +1117,6 @@ void NukiLockComponent::dump_config() {
     #endif
     #ifdef USE_NUMBER
     LOG_NUMBER(TAG, "LED Brightness", this->led_brightness_number_);
-    LOG_NUMBER(TAG, "Security Pin", this->security_pin_number_);
     LOG_NUMBER(TAG, "Timezone Offset", this->timezone_offset_number_);
     #endif
     #ifdef USE_SELECT
@@ -1140,17 +1131,25 @@ void NukiLockComponent::dump_config() {
 }
 
 void NukiLockComponent::notify(Nuki::EventType event_type) {
+    
+    // Ignore bad pin error to prevent loop
+    if(event_type == Nuki::EventType::ERROR_BAD_PIN) {
+        return;
+    }
+
     this->status_update_ = true;
     this->config_update_ = true;
     this->advanced_config_update_ = true;
     
     // Request Auth Data on every second notify, otherwise just event logs
     // Event logs are always requested after Auth Data requests
-    this->auth_data_required_ = !this->auth_data_required_;
-    if(this->auth_data_required_) {
-        this->auth_data_update_ = true;
-    } else {
-        this->event_log_update_ = true;
+    if (strcmp(event_, "esphome.none") != 0) {
+        this->auth_data_required_ = !this->auth_data_required_;
+        if(this->auth_data_required_) {
+            this->auth_data_update_ = true;
+        } else {
+            this->event_log_update_ = true;
+        }
     }
 
     ESP_LOGI(TAG, "event notified %d", event_type);
@@ -1534,11 +1533,6 @@ void NukiLockDstModeEnabledSwitch::write_state(bool state) {
 void NukiLockLedBrightnessNumber::control(float value) {
     this->parent_->set_config_number("led_brightness", value);
 }
-void NukiLockSecurityPinNumber::control(float value) {
-    this->publish_state(value);
-    this->parent_->set_security_pin(value);
-    this->parent_->save_settings();
-}
 void NukiLockTimeZoneOffsetNumber::control(float value) {
     this->parent_->set_config_number("timezone_offset", value);
 }
diff --git a/components/nuki_lock/nuki_lock.h b/components/nuki_lock/nuki_lock.h
index 039c432..9ad8a98 100644
--- a/components/nuki_lock/nuki_lock.h
+++ b/components/nuki_lock/nuki_lock.h
@@ -63,7 +63,6 @@ class NukiLockComponent : public lock::Lock, public PollingComponent, public Nuk
     #endif
     #ifdef USE_NUMBER
     SUB_NUMBER(led_brightness)
-    SUB_NUMBER(security_pin)
     SUB_NUMBER(timezone_offset)
     #endif
     #ifdef USE_SELECT
@@ -127,6 +126,7 @@ class NukiLockComponent : public lock::Lock, public PollingComponent, public Nuk
 
         void set_pairing_mode_timeout(uint16_t pairing_mode_timeout) { this->pairing_mode_timeout_ = pairing_mode_timeout; }
         void set_event(const char *event) { this->event_ = event; }
+        void set_security_pin(uint16_t security_pin) { this->security_pin_ = security_pin; }
 
         void add_pairing_mode_on_callback(std::function<void()> &&callback);
         void add_pairing_mode_off_callback(std::function<void()> &&callback);
@@ -154,8 +154,8 @@ class NukiLockComponent : public lock::Lock, public PollingComponent, public Nuk
 
         void unpair();
         void set_pairing_mode(bool enabled);
-
-        void set_security_pin(uint16_t security_pin);
+        void use_security_pin();
+        void set_override_security_pin(uint16_t security_pin);
         void save_settings();
 
         #ifdef USE_NUMBER
@@ -257,6 +257,17 @@ template<typename... Ts> class NukiLockPairingModeAction : public Action<Ts...>
         NukiLockComponent *parent_;
 };
 
+template<typename... Ts> class NukiLockSecurityPinAction : public Action<Ts...> {
+    public:
+        NukiLockSecurityPinAction(NukiLockComponent *parent) : parent_(parent) {}
+        TEMPLATABLE_VALUE(uint16_t, security_pin)
+
+        void play(Ts... x) { this->parent_->set_override_security_pin(this->security_pin_.value(x...)); }
+
+    protected:
+        NukiLockComponent *parent_;
+};
+
 // Callbacks
 class PairingModeOnTrigger : public Trigger<> {
     public:
@@ -461,13 +472,6 @@ class NukiLockLedBrightnessNumber : public number::Number, public Parented<NukiL
     protected:
         void control(float value) override;
 };
-class NukiLockSecurityPinNumber : public number::Number, public Parented<NukiLockComponent> {
-    public:
-        NukiLockSecurityPinNumber() = default;
-
-    protected:
-        void control(float value) override;
-};
 class NukiLockTimeZoneOffsetNumber : public number::Number, public Parented<NukiLockComponent> {
     public:
         NukiLockTimeZoneOffsetNumber() = default;