Skip to content

Commit

Permalink
Changed client-serv 0MP mech
Browse files Browse the repository at this point in the history
  • Loading branch information
ddetommaso committed Oct 28, 2021
1 parent 9581092 commit 362c72d
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 145 deletions.
20 changes: 0 additions & 20 deletions apps/input_loop.yml

This file was deleted.

8 changes: 5 additions & 3 deletions apps/python-examples/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from hidman.core import HIDClient, HIDKeyboard
from hidman.core import HIDClient


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

while True:
print(dev.waitEvent())
print(dev.waitKey())
print(dev.waitKey(keyList=['KEY_1']))
print(dev.waitKeyPress(keyList=['KEY_2', 'KEY_3']))
print(dev.waitKeyRelease(keyList=['KEY_4']))
6 changes: 4 additions & 2 deletions apps/python-examples/client_timeout.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from hidman.core import HIDClient, HIDKeyboard
from hidman.core import HIDClient


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

i = 0
while True:
print(dev.waitEvent(timeout_ms=3000))
i=i+1
print(i, dev.waitKeyRelease(keyList=['KEY_4'], timeout_ms=3000))
9 changes: 0 additions & 9 deletions apps/python-examples/loop.py

This file was deleted.

4 changes: 1 addition & 3 deletions apps/python-examples/server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from hidman.core import HIDServer
import evdev

selected_device = evdev.InputDevice('/dev/input/hidman0')
serv = HIDServer(device=selected_device, address="tcp://*:6666")
serv = HIDServer(device='/dev/input/hidman0', address="tcp://*:6666")
serv.run()
17 changes: 0 additions & 17 deletions apps/python-examples/test_latency.py

This file was deleted.

18 changes: 0 additions & 18 deletions apps/test_latency.yml

This file was deleted.

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.3'
__version__ = '0.5'
__description__ = 'A Python based HID (Human Interface Device) events manager'
__requirements__ = ['pytest>=6.2.4', 'evdev>=1.4.0', 'pyzmq>=22.1.0']
137 changes: 65 additions & 72 deletions hidman/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,108 +10,101 @@
class HIDDevice:

def __init__(self, device=None):
if device:
self._device = InputDevice(device)
else:
self._device = device
self._device = InputDevice(device)

def clear(self):
if self._device:
while not self._device.read_one() is None:
return
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:
# 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)
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
def read(self):
return self._device.read_one()

def close(self):
if self._device:
self._device.close()

class HIDEvent:

KEY_UP = 0
KEY_DOWN = 1
KEY_HOLD = 2

@staticmethod
def parse(event, event_type=None, event_code=None, event_status=None):
if event_type and event.type == ecodes.EV_KEY:
data = categorize(event)
if event_status is None:
if not event_code is None:
if data.keycode in event_code:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
return (data.keystate, data.keycode, ecodes.EV_KEY)
else:
if data.keystate == event_status and not event_code is None:
if data.keycode in event_code:
return (data.keystate, data.keycode, ecodes.EV_KEY)

return None


class HIDServer:

def __init__(self, device=None, address="ipc://pyboard"):
def __init__(self, device, address="ipc://pyboard"):
self._device = HIDDevice(device)
self._context = zmq.Context()
self._socket = self._context.socket(zmq.REP)
self._socket = self._context.socket(zmq.PAIR)
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
self.reply(req) #TODO: consider the reply call for multi-threading in the future
event = self._device.read()
if event:
data = categorize(event)
self._socket.send_pyobj(event)

class HIDKeyboard:
KEY_UP = 0
KEY_DOWN = 1
KEY_HOLD = 2
def __del__(self):
self._device.close()

class HIDClient:

def __init__(self, address="ipc://pyboard"):
self._address = address
self._context = zmq.Context()
self._socket = self._context.socket(zmq.REQ)
self._socket.setsockopt(zmq.LINGER, 0)
self._socket = self._context.socket(zmq.PAIR)
self._socket.connect(self._address)

def waitEvent(self, event_type=None, event_code=None, event_value=None, timeout_ms=None):
def waitEvent(self, event_type=None, event_code=None, event_status=None, timeout_ms=None):
t0 = time.perf_counter()
self._socket.send_pyobj([event_type, event_code, event_value, timeout_ms])
poller = zmq.Poller()
poller.register(self._socket, zmq.POLLIN)
if poller.poll(timeout_ms):
msg = self._socket.recv_pyobj()
else:
msg = None
return (msg, time.perf_counter()-t0)

def waitKey(self, evkey=None, evstate=None, timeout_ms=None):
return self.waitEvent(event_type=ecodes.EV_KEY, event_code=evkey, event_value=evstate, timeout_ms=timeout_ms)

def waitKeyPress(self, evkey=None, evstate=HIDKeyboard.KEY_DOWN, timeout_ms=None):
return self.waitEvent(event_type=ecodes.EV_KEY, event_code=evkey, event_value=evstate, timeout_ms=timeout_ms)

def waitKeyRelease(self, evkey=None, evstate=HIDKeyboard.KEY_UP, timeout_ms=None):
return self.waitEvent(event_type=ecodes.EV_KEY, event_code=evkey, event_value=evstate, timeout_ms=timeout_ms)
if not timeout_ms is None:
poller = zmq.Poller()
poller.register(self._socket, zmq.POLLIN)
res = None
while res is None:
if not timeout_ms is None:
elapsed_time = (time.perf_counter() - t0)*1000.0
if timeout_ms <= elapsed_time:
break
elif poller.poll(timeout_ms-elapsed_time):
event = self._socket.recv_pyobj()
res = HIDEvent.parse(event, event_type, event_code, event_status)
else:
break
else:
event = self._socket.recv_pyobj()
res = HIDEvent.parse(event, event_type, event_code, event_status)

return (res, time.perf_counter()-t0)

def waitKey(self, keyList=None, evstate=None, timeout_ms=None):
return self.waitEvent(event_type=ecodes.EV_KEY, event_code=keyList, event_status=evstate, timeout_ms=timeout_ms)

def waitKeyPress(self, keyList=None, evstate=HIDEvent.KEY_DOWN, timeout_ms=None):
return self.waitEvent(event_type=ecodes.EV_KEY, event_code=keyList, event_status=evstate, timeout_ms=timeout_ms)

def waitKeyRelease(self, keyList=None, evstate=HIDEvent.KEY_UP, timeout_ms=None):
return self.waitEvent(event_type=ecodes.EV_KEY, event_code=keyList, event_status=evstate, timeout_ms=timeout_ms)

def close(self):
self._socket.send_pyobj(None)
Expand Down

0 comments on commit 362c72d

Please sign in to comment.