     report["door_denied_count"] = door_denied_count;
     report["state"] = state[machinestate].label;
     report["opens"] = opening_door_count;
+    report["swipeouts"] = swipeouts_count;
 
 #ifdef OTA_PASSWD
     report["ota"] = true;
 #else
     report["ota"] = false;
 #endif
+  });
+
+  reader.onSwipe([](const char * tag) -> ACBase::cmd_result_t {
+
+    // special case of the someone is leaving swipe; technically
+    // we sent this as an 'ok to leave' sort of request; so the privacy
+    // of the tag/user is preserved on the wire.
+    //
+    // We expect the door to not be in the opening process; but we do
+    // allow a swipe post opening - e.g. when some-one holds the door
+    // open als someone comes in.
+    //
+    if ((machinestate == WAITINGFORCARD || machinestate >= OPEN) && digitalRead(DOOR_SENSOR) == DOOR_IS_OPEN)
+    {
+      node.request_approval(tag, "leave", NULL);
+      swipeouts_count++;
+      return ACBase::CMD_CLAIMED;
+    }
+
+    // avoid swithing messing with the door open process
+    if (machinestate > CHECKINGCARD)
+      return ACBase::CMD_CLAIMED;
+
+    // We'r declining so that the core library handle sending
+    // an approval request, keep state, and so on.
+    //
+    return ACBase::CMD_DECLINE;
   });
 
 

#define DOOR_CLOSED       (0)
#define DOOR_OPEN         (1100)
#define DOOR_OPEN_DELAY   (10*1000)

#define AARTLED_GPIO      (16)


  });
  node.onDenied([](const char * machine) {
    machinestate = REJECTED;
    door_denied_count ++;
  });

  node.onReport([](JsonObject  & report) {
