Run pyscard code in executor
authorBenjamin Braatz <bb@bbraatz.eu>
Mon, 22 Aug 2022 13:30:23 +0000 (15:30 +0200)
committerBenjamin Braatz <bb@bbraatz.eu>
Mon, 22 Aug 2022 13:30:23 +0000 (15:30 +0200)
controlpi_plugins/nfc.py

index e481eef0fe4c7b5218f36e260ed7e8410370f4f7..62870c11517ea3cdc116c68f9be8b1e2c021a9c4 100644 (file)
@@ -10,9 +10,10 @@ from controlpi.baseplugin import JSONSchema
 class ControlPiCardObserver(CardObserver):
     """Card Observer that calls ControlPi plugin on changes."""
 
-    def __init__(self, plugin):
-        """Register the plugin to be called back."""
+    def __init__(self, plugin, loop):
+        """Register the plugin to be called back and the event loop."""
         self._plugin = plugin
+        self._loop = loop
         super().__init__()
 
     def update(self, observable, handlers):
@@ -24,9 +25,13 @@ class ControlPiCardObserver(CardObserver):
             data, sw1, sw2 = connection.transmit([0xFF, 0xCA,
                                                   0x00, 0x00, 0x00])
             identifier = bytes(data).hex()
-            self._plugin._set_state(True, identifier)
+            self._loop.call_soon_thread_safe(
+                    self._plugin._set_state, True, identifier
+            )
         for card in removed:
-            self._plugin._set_state(False, "")
+            self._loop.call_soon_thread_safe(
+                    self._plugin._set_state, False, ""
+            )
 
 
 class NFCReader(BasePlugin):
@@ -72,8 +77,12 @@ class NFCReader(BasePlugin):
                                                      'state': state,
                                                      'card': card}))
 
-    async def run(self) -> None:
-        """Run no code proactively."""
+    def _monitor_card(self, loop) -> None:
         self._monitor = CardMonitor()
-        self._observer = ControlPiCardObserver(self)
+        self._observer = ControlPiCardObserver(self, loop)
         self._monitor.addObserver(self._observer)
+
+    async def run(self) -> None:
+        """Run no code proactively."""
+        loop = asyncio.get_running_loop()
+        loop.run_in_executor(None, self._monitor_card, loop)