Remontée Nuki info lockactionevent

Bonjour,
J’ai installé une Nuki Smart lock ultra.
Pour l’instant je remonte les infos par wifi/mqtt en utilisant mqtt discovery.
Presque toutes les infos remontent, sauf une qui m’intéresse :

image

elle fournit beaucoup d’infos et me permettrait d’identifier si le verrouillage est fait au moyen d’une empreinte ou de la flèche du keypad (pour activer ou pas l’alarme).
Est-ce possible de l’intégrer d’une manière ou d’une autre ?
D’avance merci
Les logs sont vides. D’ailleurs les autres infos/commandes remontent parfaitement.
Celle qui manque a un format particulier, avec plusieurs infos séparées par des virgules, est-ce la raison de la non-reconnaissance ?

Bonjour,

Veuillez lire la documentation, chapitre support, qui détails les infos nécessaires pour que je puisse répondre

désolé, post mis à jour.

Pour les infos de découverte c’est à coller (sans formater) directement dans un bloc Texte préformaté (bouton </>)

{"lock":{"nuki_4BA301BF_lock":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]","mf":"Nuki","name":"Home","mdl":"Smart Lock Ultra"},"name":"","uniq_id":"4BA301BF_lock","cmd_t":"~/lockAction","pl_lock":"2","pl_unlk":"1","pl_open":"3","qos":2,"stat_t":"~/state","stat_locked":"1","stat_locking":"4","stat_unlocked":"3","stat_unlocking":"2","stat_open":"5","stat_opening":"7","stat_jam":"254","val_tpl":"{% if value == \"6\" %}3{% else %}{{value}}{% endif %}"}},"binary_sensor":{"nuki_4BA301BF_lock_battery_critical":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Battery critical","uniq_id":"4BA301BF_lock_battery_critical","dev_cla":"battery","ent_cat":"diagnostic","stat_t":"~/batteryCritical","pl_off":"false","pl_on":"true"},"nuki_4BA301BF_battery_charging":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Battery charging","uniq_id":"4BA301BF_battery_charging","dev_cla":"battery_charging","ent_cat":"diagnostic","stat_t":"~/batteryCharging","pl_off":"false","pl_on":"true"},"nuki_4BA301BF_keypad_battery_critical":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Keypad battery critical","uniq_id":"4BA301BF_keypad_battery_critical","dev_cla":"battery","ent_cat":"diagnostic","stat_t":"~/keypadBatteryCritical","pl_off":"false","pl_on":"true"}},"sensor":{"nuki_4BA301BF_battery_percent":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Battery","uniq_id":"4BA301BF_lock_battery_percent","dev_cla":"battery","ent_cat":"diagnostic","stat_t":"~/batteryChargeState","stat_cla":"measurement","unit_of_meas":"%"},"nuki_4BA301BF_fw_version":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Firmware version","uniq_id":"4BA301BF_fw_version","icon":"mdi:wrench","ent_cat":"diagnostic","stat_t":"~/firmware"}},"button":{"nuki_4BA301BF_unlatch_button":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Unlatch","uniq_id":"4BA301BF_unlatch_button","cmd_t":"~/lockAction","pl_prs":"3","qos":2},"nuki_4BA301BF_lockngo_button":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Lock 'n' Go","uniq_id":"4BA301BF_lock_n_go_button","cmd_t":"~/lockAction","pl_prs":"4","qos":2},"nuki_4BA301BF_lock_n_go_unlatch":{"~":"nuki/4BA301BF","avty_t":"~/connected","pl_avail":"true","pl_not_avail":"false","dev":{"ids":"[4BA301BF]"},"name":"Lock 'n' Go with unlatch","uniq_id":"4BA301BF_lock_n_go_unlatch_button","cmd_t":"~/lockAction","pl_prs":"5","qos":2}}}

Bonjour.

Note : j’avais oublié que ce message avait été masqué suite à des signalements de la communauté parce que considéré comme étant hors sujet. Je me demande s’il ne s’agissait pas d’une erreur, d’une fausse manip, n’ayant jamais pu avoir accès aux commentaires de la communauté.

Par ailleurs je ne vois pas en quoi le fait d’indiquer le plugin MQTT Manager comme solution pour récupérer le topic lockActionEvent était hors sujet, la question étant “Est-ce possible de l’intégrer d’une manière ou d’une autre ?”. Dans la suite du fil l’utilisateur qui pose la question confirme avoir mis en œuvre cette solution. Ce qui permettrait d’ailleurs éventuellement de clore le sujet.

Avec MQTT Manager, je n’ai aucun problème :

J’ai par ailleurs fait développer un petit utilitaire qui traduit en clair une partie des codes :

Merci pour l’info. Du coup ce serait possible de voir la partie “Equipement” (et s’il y a quelque chose à faire dans la configuration) ? Je dois avoir une erreur quelque part.
D’avance merci

Tu peux partager ce petit utilitaire ?

Car effectivement à décoder ce n’est pas facile

Voilà (le code qui dans le topic racine suit Nuki/ sera pour vous 4BA301BF)

Bien sûr. Je l’envoie tout à l’heure.

1 « J'aime »

Voilà le scénario. Je ne me suis intéressé qu’aux 2 premiers paramètres. Je demande également un décodage de LockState.

Ce scénario peut certainement être amélioré. Je me suis aperçu depuis que “reserved” dans le décodage du déclencheur signifiait en fait “action manuelle”.
Je m’appuie bien entendu sur la doc de Nuki, version 1.5

20240730_MQTT_API_1.5.pdf (156,4 Ko)

Scénario décodage.txt (4,0 Ko)

1 « J'aime »

Merci, maintenant ça fonctionne.
Par contre attention car avec ma serrure Nuki Smart Lock Ultra v5 et le 5.7.10, les données de l’info lockActionEvent ont changé. Je n’ai pas trouvé de documentation mise à jour mais mes observations sont les suivantes :
ouverture/fermeture par empreinte : 0,0,id probablement du keypad, id utilisateur,2
ouverture/fermeture par code : 0,0,id probablement du keypad, id utilisateur,1
fermeture flèche du keypad : 2,0,id probablement du keypad,0,0
fermeture bouton physique du Nuki : 2,2,0,0,2

Bonsoir. Est-ce que ça fonctionne avec MQTT Discovery ou avec MQTT Manager ?

une partie des commandes avec mqtt discovery et celle manquante dont j’avais besoin avec mqtt manager (on ne peut pas créer de commande dans discovery).

Avec l’aide de l’IA j’ai pu créer un scénario qui permet d’enclencher l’alarme selon la méthode de verrouillage (code/empreinte = alarme), flèche du clavier = fermeture mais sans alarme (encore quelqu’un à l’intérieur par exemple).
J’utilise aussi des nuts pour activer/désactiver, mais comme je vais avoir mes petits-enfants à proximité, je ne souhaite pas leur donner une clé. Ils pourront ainsi entrer avec empreinte digitale et l’alarme se désactivera.

Bonsoir.

Sur le site développeur de Nuki (About the MQTT category - MQTT - Nuki Developers), j’ai trouvé une version actualisée de la doc sur l’API MQTT, qui est maintenant en version 1.6. Si ça peut servir.

MQTT API 1.6.pdf (278,9 Ko)

Hello,

J’utilise aussi un bloc code de décodage, qui génère des tags

[2026-06-21 15:02:15][SCENARIO] ┌────────────▶︎ Tag ◀──────────────
[2026-06-21 15:02:15][SCENARIO] | lockActionEvent ─▶︎ 1,0,12345,6789,2
[2026-06-21 15:02:15][SCENARIO] | Tag  ─▶︎ action = Déverrouiller
[2026-06-21 15:02:15][SCENARIO] | Tag  ─▶︎ trigger = système ou bluetooth
[2026-06-21 15:02:15][SCENARIO] | Tag  ─▶︎ authId = Keypad
[2026-06-21 15:02:15][SCENARIO] | Tag  ─▶︎ key = fingerprint
[2026-06-21 15:02:15][SCENARIO] | Tag  ─▶︎ user = Phpvarious
[2026-06-21 15:02:15][SCENARIO] |┌────────────▶︎ widget perso ◀──────────────
[2026-06-21 15:02:15][SCENARIO] || Tag  ─▶︎ lastUser = Margo_fingerprint
[2026-06-21 15:02:15][SCENARIO] |└───────────────────────────────────────────
[2026-06-21 15:02:15][SCENARIO] └───────────────────────────────────────────

Pour ma part j’utilise que le user et seulement sur déverrouillage, je génère un tag lastUser ce qui permet d’alimenter un virtuel pour ainsi visualiser qui a déverrouillé en dernier :

3 « J'aime »

C’est genial, peux tu partagé comment tu as fait stp ?

Préalable


Il semble pas possible d’avoir lockActionEvent directement dans MQTTDiscovery.
Il faut donc récupérer l’info par mqtt2 ou jMQTT.

1) Widget


Supprimer l’extension .txt puis déposer dans data/customTemplates/dashboard/
cmd.info.string.user_nuki.html.txt (3,4 Ko)

Créer ensuite le dossier cmd.info.string.user_nuki dans ce même dossier, c’est dans ce dossier qu’il faudra ajouter vos images perso des users.

Attention, les images custom devront avoir un nom bien défini en fonction du name que vous aurez paramétré dans authId. (plus de détails en section 4)

Exemple pour cet authId
1111 => array('type' => 'keypad_user', 'name' => 'Phpvarious'),
J’aurais donc une image Phpvarious.png a mettre dans le dossier cmd.info.string.user_nuki

2) Virtuel ou équipement

Pour ma part je n’ai pas créé de virtuel juste pour cette commande, étant sur le plugin mqtt2 j’ai juste ajouter une commande Info/Autre (possible aussi sur Jmqtt) que j’ai nommée LastUser.
Attribuer lui le widget précédemment mis en place.

3) Scénario


Creer un nouveau scénario et mettre comme déclencheur lockActionEvent
Ajouter un bloc code et copier / coller le code ci-dessous :

Bloc code
/////////////////////// Configuration des Auth-ID //////////////////////////////////
/////////////////////// Configuration OF Auth-ID ///////////////////////////////////

// Please respect the type of each category because it allows the Auth-ID to be differentiated in the rest of the code.
// Veuillez a respecter le type de chaque catégorie parce qu'il permet de différencier le Auth-ID dans la suite du code.

$_authId = array(
  // utilisateurs programmés dans le keypad | users programmed into the keypad
  // type keypad_user
  1111 => array('type' => 'keypad_user',	'name' => 'Phpvarious'),
  2222 => array('type' => 'keypad_user',	'name' => 'Nom2'),
  // type keypad
  33333 => array('type' => 'keypad',		'name' => 'Keypad'),
  // type app
  44444 => array('type' => 'app',			'name' => 'Nom1-app'),
  // type fob
  55555 => array('type' => 'fob',			'name' => 'Nom1-fob')
);

//////////////////////// conversion //////////////////////////////
$_lockActions = array(
  1 => 'Déverrouiller',							// unlock
  2 => 'Verrouiller',							// lock
  3 => 'Déverrouiller avec ouverture',			// unlatch
  4 => 'verrouiller et partir',					// lock'n'go
  5 => 'verrouiller et partir avec ouverture',	// lock'n'go with unlatch
  6 => 'verrouillage complet',					// full lock
  80 => 'porte-clés',							// fob (sans action programmée // without programmed action)
  90 => 'bouton '								// button (sans action programmée // without programmed action)
);

$_trigger = array(
  0 => 'système ou bluetooth',					// system or bluetooth command
  1 => 'manuel',								// reserved
  2 => 'bouton',								// button
  3 => 'automatique',							// automatic (e.g. time control)
  6 => 'auto verrouillage',						// auto lock
  171 => 'HomeKit ou Matter',					// HomeKit / Matter
  172 => 'mqtt'									// MQTT
);

$_options = array(
  'keypad' => array(0 => 'back', 1 => 'code', 2 => 'fingerprint')
);

///////////////////////// DATA PROCESSING //////////////////////////////////////
// Récupère la liste des tags
// Retrieves the list of tags
$tags = $scenario->getTags();

// La fonction getRealTriggerValue() a été supprimée dans la version 4.5 et remplacée par la balise #trigger_value#.
// getRealTriggerValue() was removed in 4.5, it was replaced by tag #trigger_value#
if(method_exists("scenario", "getRealTriggerValue")) { 
  $tags['#trigger_value#'] = $scenario->getRealTriggerValue();
}

$scenario->setLog('┌────────────▶︎ Tag ◀──────────────');
$scenario->setLog('| lockActionEvent ─▶︎ ' . $tags['#trigger_value#']);
$array = explode(",", $tags['#trigger_value#']);

if (count($array) >= 5) {
  
  //// VAR ////
  $lockActions = $array[0];
  $trigger = $array[1];
  $authId = $array[2]; // Auth-ID of the user
  $userId = $array[3]; // ID of the Keypad code, 0= unknown
  $option = $array[4]; //Auto-Unlock (0 or 1) or number of button presses (only button & fob actions) or Keypad source (0 = back key, 1 = code, 2 = fingerprint)
  
  //// LOGs AND TAGs //// 
  if (isset($_lockActions[$lockActions])) {
    $scenario->setLog('| Tag  ─▶︎ action = ' . $_lockActions[$lockActions]);
    $tags['#action#'] = $_lockActions[$lockActions];
    if ($lockActions == '80' || $lockActions == '90') { // fob or button not configured.
      $tags['#nbPressButton#'] = $option;
      $scenario->setLog('| Tag  ─▶︎ nbPressButton = ' . $tags['#nbPressButton#']);
    }
  }
  if (isset($_trigger[$trigger])) {
    $scenario->setLog('| Tag  ─▶︎ trigger = ' . $_trigger[$trigger]);
    $tags['#trigger#'] = $_trigger[$trigger];
    if ($trigger == '2') { // button
      $tags['#nbPressButton#'] = $_trigger[$trigger];
      $scenario->setLog('| Tag  ─▶︎ nbPressButton = ' . $tags['#nbPressButton#']);
    }
  }
  if ($authId != '0' && isset($_authId[$authId]) && isset($_authId[$authId]['name'])) {
    $tags['#authId#'] = $_authId[$authId]['name'];
    $scenario->setLog('| Tag  ─▶︎ authId = ' . $tags['#authId#']);
    if (isset($_authId[$authId]['type'])) {
      if (isset($_options[$_authId[$authId]['type']]) && isset($_options[$_authId[$authId]['type']][$option])) {
        $tags['#key#'] = $_options[$_authId[$authId]['type']][$option];
        $scenario->setLog('| Tag  ─▶︎ key = ' . $tags['#key#']);
      }
    }
  }
  if ($userId != '0' && isset($_authId[$userId])) {
    $tags['#user#'] = $_authId[$userId]['name'];
    $scenario->setLog('| Tag  ─▶︎ user = ' . $tags['#user#']);
  }
  

  /// for widget perso cmd.info.string.user_nuki ///
  if ($lockActions == '1') { // unlock
    $scenario->setLog('|┌────────────▶︎ widget perso ◀──────────────');
    if ($trigger == '172') {  // MQTT
        $tags['#lastUser#'] = $_trigger[$trigger];
        $scenario->setLog('|| Tag  ─▶︎ lastUser = ' . $tags['#lastUser#']);
    } else if ($trigger == '0') { // system / bluetooth 
      if ($authId != '0' && isset($_authId[$authId]) && isset($_authId[$authId]['name'])) {
        if (isset($_authId[$authId]['type']) && $_authId[$authId]['type'] == 'keypad') {
          if ($userId != '0' && isset($_authId[$userId])) {
            if (isset($_authId[$userId]['name'])) {
              $user = $_authId[$userId]['name'];
              if (isset($_options[$_authId[$authId]['type']][$option])) {
                $user .= '_' . $_options[$_authId[$authId]['type']][$option];
              }
              $tags['#lastUser#'] = $user;
            }
          //if (isset($_options[$_authId[$authId]['type']]) && isset($_options[$_authId[$authId]['type']][$option])) {
            //$user = $_authId[$authId]['name'];
          }
        } else {
          $user = $_authId[$authId]['name'];
          $tags['#lastUser#'] = $user;
        }
        $scenario->setLog('|| Tag  ─▶︎ lastUser = ' . $user);
      }
    }
    $scenario->setLog('|└───────────────────────────────────────────');
  } else if ($lockActions == '2') { // LockAction = lock
    // 
  }
}
$scenario->setTags($tags);
$scenario->setLog('└───────────────────────────────────────────');

La partie $_authId sera a modifier/ajouter en fonction des id remontés par votre nuki, mais on verra cette partie un peu plus bas a la section 4.

Ce bloc code permet de mettre a disposition plusieurs tags, exemple :

[2026-06-21 19:19:40][SCENARIO] ┌────────────▶︎ Tag ◀──────────────
[2026-06-21 19:19:40][SCENARIO] | lockActionEvent ─▶︎ 1,0,33333,1234,1
[2026-06-21 19:19:40][SCENARIO] | Tag  ─▶︎ action = Déverrouiller
[2026-06-21 19:19:40][SCENARIO] | Tag  ─▶︎ trigger = système ou bluetooth
[2026-06-21 19:19:40][SCENARIO] | Tag  ─▶︎ authId = Keypad
[2026-06-21 19:19:40][SCENARIO] | Tag  ─▶︎ key = code
[2026-06-21 19:19:40][SCENARIO] | Tag  ─▶︎ user = Naomy
[2026-06-21 19:19:40][SCENARIO] |┌────────────▶︎ widget perso ◀──────────────
[2026-06-21 19:19:40][SCENARIO] || Tag  ─▶︎ lastUser = Naomy_code
[2026-06-21 19:19:40][SCENARIO] |└───────────────────────────────────────────
[2026-06-21 19:19:40][SCENARIO] └───────────────────────────────────────────

Le tag lastUser est spécialement conçu pour le widget, il sera généré que si l’action est un déverrouillage.
C’est pourquoi j’utilise ensuite un bloc si tag(lastUser,false) != 'false', qui mettra a jour ma commande lastUser de mon virtuel (ou equipement)

Bloc Si

A ajouter juste après le bloc code, il permet de faire un event sur ma commande lastUser (créée a l’étape 2) qui contient le widget custom :
image

4) Récupérer les authId

Pour récupérer les authId il faudra analyser la donnée lockActionEvent qui est envoyé par mqtt lorsque vous effectuez un déverrouillage, soit en analysant la valeur direct dans votre plugin (mqtt, jMqtt…) soit en regardant les log du scénario.

Exemple 1 :
Je déverrouille depuis l’app, le payload envoyé est 1,0,44444,0,0
je sais donc que l’id de l’user utilisé sur mon app est 44444
j’ajoute maintenant cet authId dans la config du bloc code, pour qu’il puisse reconnaitre l’user :
44444 => array('type' => 'app', 'name' => 'Nom1-app'),
(il me faudra donc une image nommée Nom1-app.png dans le dossier des image du widget.)

Exemple 2 :
Je déverrouille a l’aide de mon code d’accès sur le keypad : 1,0,33333,1111,1
Je peut en déduire 2 choses

  • mon keypad utilise l’id 33333
  • et l’utilisateur utilise l’id 1111

j’ajoute maintenant ces 2 authId dans le bloc code :
33333 => array('type' => 'keypad', 'name' => 'Keypad'),
1111 => array('type' => 'keypad_user', 'name' => 'Phpvarious'),

Pour le keypad, il sera a insérer une seul fois dans le bloc code, car il sera toujours le même quelque soit la personne qui déverrouille. Il ne nécessite aucune image dans le dossier

Pour tous ces exemples, vous pouvez choisir le name que vous souhaitez mais ne surtout pas utiliser de caractère _ sinon le widget pourrait mal l’interprèter.
Attention le type a son importance aussi, pour

  • un user sur keypad 'type' => 'keypad_user'
  • un user sur l’app 'type' => 'app'
  • le keypad 'type' => 'keypad'
  • fob 'type' => 'fob' // j’ai pas de fob, donc jamais testé
1 « J'aime »

>> Fait

>> largué :frowning: … je vois mes Nuki sous MQTTDiscovery mais je ne vois pas comment rajouter une commande, une idée stp

Le bloc code est a mettre ou stp ?

Merci de ton aide et précision.

Ben tu crées un virtuel