Skip to content

Commit

Permalink
Fixed waitEvent with timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
ddetommaso committed Oct 27, 2021
1 parent 7273597 commit 9581092
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 19 deletions.
2 changes: 1 addition & 1 deletion apps/.env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
HIDMAN_DEVICE=/dev/input/event7
HIDMAN_DEVICE=/dev/input/event6
29 changes: 29 additions & 0 deletions apps/client_server_timeout.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: '3.7'

x-hidmanbase: &hidman-base

volumes:
- type: bind
source: ../
target: /usr/local/src/hidman

image: iitschri/hidman:latest

privileged: true
stdin_open: true
tty: true
network_mode: host

services:

hidman-server:
<<: *hidman-base
command: python3 /usr/local/src/hidman/apps/python-examples/server.py
devices:
- ${HIDMAN_DEVICE}:/dev/input/hidman0

hidman-client:
<<: *hidman-base
command: python3 /usr/local/src/hidman/apps/python-examples/client_timeout.py
depends_on:
- hidman-server
7 changes: 7 additions & 0 deletions apps/python-examples/client_timeout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from hidman.core import HIDClient, HIDKeyboard


dev = HIDClient(address="tcp://localhost:6666")

while True:
print(dev.waitEvent(timeout_ms=3000))
2 changes: 1 addition & 1 deletion hidman/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__authors__ = 'Davide De Tommaso'
__emails__ = '[email protected]'
__license__ = 'MIT'
__version__ = '0.2'
__version__ = '0.3'
__description__ = 'A Python based HID (Human Interface Device) events manager'
__requirements__ = ['pytest>=6.2.4', 'evdev>=1.4.0', 'pyzmq>=22.1.0']
51 changes: 34 additions & 17 deletions hidman/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import zmq
import statistics
import logging
import threading
from select import select

class HIDDevice:

Expand All @@ -20,25 +22,34 @@ def clear(self):
return

def waitEvent(self, event_type=None, event_code=None, event_value=None, timeout_ms=None, clear_events=True):

if clear_events:
self.clear()
if self._device:
for event in self._device.read_loop():
if not event_type is None:
if event.type == event_type:
data = categorize(event)
if not event_value is None:
if data.keystate == event_value:
return (data.keystate, data.keycode, ecodes.EV_KEY)
if not event_code is None:
if event_code == data.keycode:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
# In order to respect REQ and REP archetypes in ZMQ the client should receive a reply right before the timeout
if timeout_ms is None:
r = True
else:
r, w, x = select([self._device], [], [], timeout_ms/1000.0 - 0.01)
if r:
for event in self._device.read_loop():
if not event_type is None:
if event.type == event_type:
data = categorize(event)
if not event_value is None:
if data.keystate == event_value:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
return (event.code, event.value)
if not event_code is None:
if event_code == data.keycode:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
return (event.code, event.value)
else: #Timeout reached
return None
else:
return None

Expand All @@ -53,22 +64,28 @@ def __init__(self, device=None, address="ipc://pyboard"):
self._context = zmq.Context()
self._socket = self._context.socket(zmq.REP)
self._socket.bind(address)
self._socket_lock = threading.Lock()

def reply(self, req):
res = self._device.waitEvent(event_type=req[0], event_code=req[1], event_value=req[2], timeout_ms=req[3])
with self._socket_lock:
self._socket.send_pyobj(res)

def run(self):
while True:
req = self._socket.recv_pyobj()
if req is None:
self._device.close()
return
res = self._device.waitEvent(event_type=req[0], event_code=req[1], event_value=req[2], timeout_ms=req[3])
self._socket.send_pyobj(res)
self.reply(req) #TODO: consider the reply call for multi-threading in the future

class HIDKeyboard:
KEY_UP = 0
KEY_DOWN = 1
KEY_HOLD = 2

class HIDClient:

def __init__(self, address="ipc://pyboard"):
self._address = address
self._context = zmq.Context()
Expand Down

0 comments on commit 9581092

Please sign in to comment.