No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

buttonreader.py 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # Licensed under GPLv3
  2. # Written by Sebastian Lohff (seba@someserver.de)
  3. # http://seba-geek.de/projects/seopardy/
  4. from __future__ import print_function
  5. import os
  6. import serial
  7. import socket
  8. from PySide import QtCore
  9. _inputs = {}
  10. def _add_input(inputType, inputClass):
  11. global _inputs
  12. _inputs[inputType] = inputClass
  13. def get_input(inputType, args, app):
  14. global _inputs
  15. if inputType not in _inputs:
  16. raise ValueError("'%s' is an unknown input type" % inputType)
  17. return _inputs[inputType](app, *args)
  18. class BaseInput(QtCore.QThread):
  19. buttonEvent = QtCore.Signal(int)
  20. def __init__(self, app, parent=None):
  21. super(BaseInput, self).__init__(parent)
  22. self._app = app
  23. def _sendButtonEvent(self, btn):
  24. self.buttonEvent.emit(int(btn))
  25. @QtCore.Slot(bool)
  26. def buzzersOpen(self, isOpen):
  27. """ Called when buzzers are opened or closed for answering
  28. isOpen - True if question got opened, False if closed
  29. """
  30. #print("Buzzers are now " + ("open" if isOpen else "closed"))
  31. pass
  32. @QtCore.Slot(int)
  33. def playerGotQuestion(self, playerNo):
  34. """ Called when a player got its turn to answer the question
  35. playerNo - number (int) of player which can answer (starting from 1)
  36. """
  37. #print("player %d can answer now" % playerNo)
  38. pass
  39. class SerialInput(BaseInput):
  40. def __init__(self, app, device, baudrate=9600, bytesize=8, parity='N', stopbits=1):
  41. super(SerialInput, self).__init__(app)
  42. try:
  43. self._serial = serial.Serial(device, baudrate, bytesize, parity, stopbits)
  44. except serial.SerialException as e:
  45. raise InputException("Error: %s" % e)
  46. print(" >> serial %s initialized with rate %s %s%s%s" % (device, baudrate, bytesize, parity, stopbits))
  47. def run(self):
  48. while True:
  49. c = self._serial.read(1)
  50. if len(c) == 1 and ord(c) > ord('0') and ord(c) <= ord('9'):
  51. self._sendButtonEvent(c)
  52. _add_input("Serial", SerialInput)
  53. class BeopardySerialInput(BaseInput):
  54. def __init__(self, app, device, baudrate=9600, bytesize=8, parity='N', stopbits=1):
  55. super(BeopardySerialInput, self).__init__(app)
  56. try:
  57. self._serial = serial.Serial(device, baudrate, bytesize, parity, stopbits)
  58. except serial.SerialException as e:
  59. raise InputException("Error: %s" % e)
  60. # playerDict
  61. self._playerDict = {
  62. 'a': 1,
  63. 'b': 2,
  64. 'c': 3,
  65. 'd': 4,
  66. }
  67. print(" >> serial %s initialized with rate %s %s%s%s" % (device, baudrate, bytesize, parity, stopbits))
  68. def run(self):
  69. while True:
  70. c = self._serial.read(1)
  71. #print("serial: read ", c)
  72. if len(c) == 1 and c in self._playerDict:
  73. #print("sending button event ", c, " ", self._playerDict[c])
  74. self._sendButtonEvent(self._playerDict[c])
  75. @QtCore.Slot(bool)
  76. def buzzersOpen(self, isOpen):
  77. self._serial.write("ABCD")
  78. #print("serial: ABCD")
  79. if isOpen:
  80. # buzzers are open now
  81. self._serial.write("R")
  82. #print("serial: R")
  83. else:
  84. # tell them that buttons are closed now
  85. self._serial.write("r")
  86. #print("serial: r")
  87. @QtCore.Slot(int)
  88. def playerGotQuestion(self, playerNo):
  89. if not (playerNo >= 1 and playerNo <= 4):
  90. return
  91. self._serial.write(chr(ord('a') + (playerNo-1)))
  92. #print("serial: ", chr(ord('a') + (playerNo-1)))
  93. _add_input("BeopardySerial", BeopardySerialInput)
  94. class FifoInput(BaseInput):
  95. def __init__(self, app, fifoPath, debug=False):
  96. super(FifoInput, self).__init__(app)
  97. self._path = fifoPath
  98. self._debug = debug
  99. if not os.path.exists(self._path):
  100. try:
  101. os.mkfifo(self._path)
  102. except OSError as e:
  103. raise InputException("Could not create fifo '%s': %s" % (self._path, e))
  104. if os.path.isfile(self._path) or os.path.isdir(self._path):
  105. raise InputException("Fifo '%s' is not a fifo" % self._path)
  106. print(" >> Fifo initialized, using '%s'" % self._path)
  107. def run(self):
  108. fifo = open(self._path)
  109. while True:
  110. c = fifo.read(1)
  111. if len(c) == 1 and ord(c) > ord('0') and ord(c) <= ord('9'):
  112. self._sendButtonEvent(c)
  113. _add_input("Fifo", FifoInput)
  114. class UnixInput(BaseInput):
  115. def __init__(self, app, socketPath, debug=False):
  116. super(UnixInput, self).__init__(app)
  117. self._path = socketPath
  118. self._debug = debug
  119. self._currConn = None
  120. try:
  121. os.unlink(self._path)
  122. except OSError as e:
  123. if os.path.exists(self._path):
  124. raise InputException("Could not create domain socket '%s': %s" % (self._path, e))
  125. self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  126. self.sock.bind(self._path)
  127. print(" >> Unix domain socket initialized, using '%s'" % self._path)
  128. def run(self):
  129. self.sock.listen(1)
  130. while True:
  131. self._currConn, cli = self.sock.accept()
  132. try:
  133. while True:
  134. c = self._currConn.recv(1)
  135. if c == '':
  136. break
  137. if len(c) == 1 and ord(c) > ord('0') and ord(c) <= ord('9'):
  138. self._sendButtonEvent(c)
  139. finally:
  140. self._currConn.close()
  141. self._currConn = None
  142. @QtCore.Slot(bool)
  143. def buzzersOpen(self, isOpen):
  144. if self._currConn:
  145. if isOpen:
  146. self._currConn.send("O")
  147. else:
  148. self._currConn.send("C")
  149. @QtCore.Slot(int)
  150. def playerGotQuestion(self, playerNo):
  151. if self._currConn:
  152. self._currConn.send("T%d" % playerNo)
  153. _add_input("Unix", UnixInput)
  154. class InputException(Exception):
  155. pass