diff --git a/src/open_ephys/__init__.py b/src/open_ephys/__init__.py index 5becc17..5c4105c 100755 --- a/src/open_ephys/__init__.py +++ b/src/open_ephys/__init__.py @@ -1 +1 @@ -__version__ = "1.0.0" +__version__ = "1.0.1" diff --git a/src/open_ephys/streaming/README.md b/src/open_ephys/streaming/README.md index d5f5434..caf5435 100644 --- a/src/open_ephys/streaming/README.md +++ b/src/open_ephys/streaming/README.md @@ -85,3 +85,30 @@ stream.start(ttl_callback=ttl_callback, To stop listening, press `ctrl-C`. + +### Running the event listener in a separate thread + +To receive and respond to events in a separate thread, you can use the Python `threading` library: + +```python +import threading +from open_ephys.streaming import EventListener + +stream = EventListener(port=5557) + +thread = threading.Thread( + target = stream.start, + args = (ttl_callback, spike_callback), # Arguments to the target function + daemon = True # Ensures the main program doesn't exit when the thread finishes + ) + +thread.start() +``` + +To stop listening, call the `EventListener.stop()` method, and allow the thread to shut down gracefully by calling `thread.join()`: + +```python +stream.stop() +thread.join() +``` + diff --git a/src/open_ephys/streaming/event_listener.py b/src/open_ephys/streaming/event_listener.py index a67382f..baae1fe 100644 --- a/src/open_ephys/streaming/event_listener.py +++ b/src/open_ephys/streaming/event_listener.py @@ -24,6 +24,7 @@ import zmq import json +import threading def default_spike_callback(info): @@ -99,6 +100,8 @@ def __init__(self, ip_address="127.0.0.1", port=5557): self.socket = self.context.socket(zmq.SUB) self.socket.connect(self.url) self.socket.setsockopt(zmq.SUBSCRIBE, b"") + self.socket.setsockopt(zmq.RCVTIMEO, 1000) # 1 second timeout + self._stop_event = threading.Event() print("Initialized EventListener at " + self.url) @@ -120,8 +123,9 @@ def start( """ print("Starting EventListener") + self._stop_event.clear() # Clear stop event - while True: + while not self._stop_event.is_set(): try: parts = self.socket.recv_multipart() @@ -133,7 +137,18 @@ def start( spike_callback(info) else: ttl_callback(info) - + except zmq.Again: + # Timeout occurred, continue loop to check stop flag + continue except KeyboardInterrupt: - print() # Add final newline + print("Stopped by KeyboardInterrupt") + break + except Exception as e: + print(f"Error: {e}") break + + print("EventListener stopped") + + def stop(self): + """Call this method to stop the listener""" + self._stop_event.set()