diff --git a/babyfut.py b/babyfut.py
index 049bba0d2b1fe21123d547f2a20c5e3a24c8b26d..521b4460d8b20c9673338cdb536b959025202fc3 100644
--- a/babyfut.py
+++ b/babyfut.py
@@ -28,20 +28,18 @@ def getMainWin():
ON_RASP = os.uname()[1] == 'raspberrypi'
IMG_PATH = getContent('img')
-SIDE = None
if __name__=='__main__':
__package__ = 'Babyfut'
from Babyfut.ui.mainwin import MainWin
from Babyfut.modules import GameModule
from Babyfut.core.player import Side
- from Babyfut.core.input import GPIOThread
+ from Babyfut.core.input import Input
from Babyfut.core.downloader import Downloader
from Babyfut.core.database import Database
from Babyfut.core.replay import Replay as ReplayThread
try:
- SIDE = Side.Left
#logging.basicConfig(filename='babyfoot.log', level=logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
@@ -56,9 +54,10 @@ if __name__=='__main__':
threadReplay.start()
myapp.dispatchMessage({'replayThread': threadReplay}, toType=GameModule)
- threadGPIO = GPIOThread()
- threadGPIO.rfidReceived.connect(myapp.rfidHandler)
- threadGPIO.start()
+ input = Input()
+ input.rfidReceived.connect(lambda side: myapp.dispatchMessage({'rfid': rfid, 'source': side}))
+ input.goalDetected.connect(lambda side: myapp.dispatchMessage({'goal': True, 'source': side}))
+ input.start()
threadDownloader = Downloader.instance()
threadDownloader.start()
@@ -66,18 +65,16 @@ if __name__=='__main__':
myapp.show()
app.exec_()
- threadDownloader.stop()
- threadGPIO.stop()
if ReplayThread.isCamAvailable():
threadReplay.stop()
threadReplay.join()
- threadGPIO.join()
+ input.stop()
+ threadDownloader.stop()
threadDownloader.join()
finally:
- GPIOThread.clean()
Database.instance().close()
for f in glob.glob(join(IMG_PATH, '*')):
os.remove(f)
diff --git a/core/ginger.py b/core/ginger.py
index f8326b0454738f2d6460f6a4517594117247cd6d..00f00f36eac038665e26706972ed6ee79e7648e2 100644
--- a/core/ginger.py
+++ b/core/ginger.py
@@ -14,8 +14,8 @@ class Ginger(object):
def __init__(self):
if Ginger._instance!=None:
- self.url = Settings['ginger.url']
self.api_key = Settings['ginger.key']
+ self.url = Ginger.URL
@property
@staticmethod
@@ -25,7 +25,7 @@ class Ginger(object):
return Ginger._instance
@staticmethod
- def call(endpoint, params={}):
+ def get(endpoint, params={}):
# Add the API key to the parameter list
params['key'] = Ginger.instance.api_key
diff --git a/core/input.py b/core/input.py
index 70f993e66b35147138cd259cb92548add4a1767c..bfcc035fdf99a82838cedff08128744e95256248 100644
--- a/core/input.py
+++ b/core/input.py
@@ -7,18 +7,34 @@
import logging
import time
from threading import Thread
-import pyautogui # PyPi library
from PyQt5.QtCore import QObject, pyqtSignal
from Babyfut.babyfut import ON_RASP
from Babyfut.core.player import Side
+from Babyfut.core.settings import Settings
if ON_RASP:
import RPi.GPIO as GPIO
from pirc522 import RFID # PyPi library
+ import pyautogui # PyPi library
+
+class Input(QObject):
+ '''
+ Defines pins. Uses BCM pin identifiers
+ '''
+
+ _RFIDPins = {
+ 'pin_rst': 25,
+ 'pin_ce' : 8,
+ 'pin_irq': 24
+ }
+
+ _GoalPins = {
+ 'pin_trig': 4,
+ 'pin_echo': 16
+ }
-class GPIOThread(Thread, QObject):
_keyButtonBindings = {
26: 'up',
22: 'left',
@@ -28,36 +44,77 @@ class GPIOThread(Thread, QObject):
18: 'escape'
}
- rfidReceived = pyqtSignal(str)
+ rfidReceived = pyqtSignal(Side, str)
+ goalDetected = pyqtSignal(Side)
def __init__(self):
- Thread.__init__(self)
QObject.__init__(self)
- self.continueRunning = True
- self.lastRFIDReception = 0
if ON_RASP:
- self.rf_reader = RFID(pin_rst=25, pin_ce=8, pin_irq=24, pin_mode=GPIO.BCM)
- GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
-
- for pin in GPIOThread._keyButtonBindings.keys():
- print(pin)
+ for pin in Input._keyButtonBindings.keys():
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
- GPIO.add_event_detect(pin, GPIO.RISING, callback=self.handleButtonPress)
+ GPIO.add_event_detect(pin, GPIO.RISING, callback=self._handleButtonPress)
- def run(self):
+ self.side = Side.Left if Settings['app.side']=='left' else Side.Right
+ print(self.side)
+ self.rfidThread = RFIDThread(self, **Input._RFIDPins)
+ self.goalThread = GoalThread(self, **Input._GoalPins)
+
+ def start(self):
+ if ON_RASP:
+ self.rfidThread.start()
+ self.goalThread.start()
+
+ def stop(self):
if ON_RASP:
- try:
- while self.continueRunning:
- self.rf_reader.wait_for_tag()
- (error, tag_type) = self.rf_reader.request()
- if not error:
- self.handleRFID()
- finally:
- self.clean()
-
- def handleRFID(self):
+ self.rfidThread.stop(); self.rfidThread.join()
+ self.goalThread.stop(); self.goalThread.join()
+
+ def _handleButtonPress(self, button_pin):
+ if button_pin not in Input._keyButtonBindings.keys():
+ logging.warn('Unknown button pin: {}'.format(button_pin))
+ else:
+ key = Input._keyButtonBindings[button_pin]
+ logging.debug('Sending {} as {}'.format(button_pin, key))
+ pyautogui.press(key)
+
+class GPIOThread(Thread):
+ def __init__(self):
+ Thread.__init__(self)
+ self._running = True
+
+ def running(self):
+ return self._running
+
+ def start(self):
+ Thread.start(self)
+
+ def stop(self):
+ self._running = False
+
+ def clean(self):
+ GPIO.cleanup()
+
+class RFIDThread(GPIOThread):
+ def __init__(self, parent, **pins):
+ GPIOThread.__init__(self)
+ self.parent = parent
+ self.lastRFIDReception = 0
+ self.rf_reader = RFID(**pins, pin_mode=GPIO.BCM)
+ print(self.rf_reader.pin_rst, self.rf_reader.pin_ce, self.rf_reader.pin_irq)
+
+ def run(self):
+ try:
+ while self.running():
+ self.rf_reader.wait_for_tag()
+ (error, tag_type) = self.rf_reader.request()
+ if not error:
+ self._handleRFID()
+ finally:
+ self.clean()
+
+ def _handleRFID(self):
(error, id) = self.rf_reader.anticoll()
if not error:
# Prevent RFID "spam" (one second removal delay)
@@ -65,30 +122,59 @@ class GPIOThread(Thread, QObject):
if self.lastRFIDReception!=0 and abs(self.lastRFIDReception-now)>1:
self.lastRFIDReception = 0
receivedRFID = ':'.join([str(x) for x in id])
- self.rfidReceived.emit(receivedRFID)
+ self.input.emit(self.parent.side, receivedRFID)
logging.debug('Received RFID: {}'.format(receivedRFID))
else:
self.lastRFIDReception = now
- def handleButtonPress(self, button_pin):
- if button_pin not in GPIOThread._keyButtonBindings.keys():
- logging.warn('Unknown button pin: {}'.format(button_pin))
- else:
- key = GPIOThread._keyButtonBindings[button_pin]
- logging.debug('Sending {} as {}'.format(button_pin, key))
- pyautogui.press(key)
-
def stop(self):
- self.continueRunning = False
- # Falsely trigger the rfid reader to stop it waiting
- if ON_RASP:
- self.rf_reader.irq.set()
+ GPIOThread.stop(self)
+
+ # Falsely trigger the rfid reader to stop it from waiting
+ self.rf_reader.irq.set()
def clean(self):
- GPIOThread.clean()
+ GPIOThread.clean(self)
self.rf_reader.cleanup()
- @staticmethod
- def clean():
- if ON_RASP:
- GPIO.cleanup()
+class GoalThread(GPIOThread):
+ def __init__(self, parent, pin_trig, pin_echo):
+ GPIOThread.__init__(self)
+ self.parent = parent
+ self.pin_trig = pin_trig
+ self.pin_echo = pin_echo
+
+ GPIO.setmode(GPIO.BCM)
+ GPIO.setup (self.pin_echo, GPIO.IN)
+ GPIO.setup (self.pin_trig, GPIO.OUT)
+ GPIO.output(self.pin_trig, GPIO.LOW)
+ print(self.pin_trig, pin_echo)
+
+ def run(self):
+ try:
+ # Waiting for sensor to settle
+ time.sleep(2)
+
+ while self.running():
+ # Trigger a scan
+ GPIO.output(self.pin_trig, GPIO.HIGH)
+ time.sleep(0.00001)
+ GPIO.output(self.pin_trig, GPIO.LOW)
+
+ # Read the echo
+ while self.running() and GPIO.input(self.pin_echo)==0:
+ pulse_start_time = time.time()
+ while self.running() and GPIO.input(self.pin_echo)==1:
+ pulse_end_time = time.time()
+
+ if self.running():
+ pulse_duration = pulse_end_time - pulse_start_time
+ distance = round(pulse_duration * 17150, 2)
+ self._handle_dist(distance)
+ finally:
+ self.clean()
+
+ def _handle_dist(self, dist):
+ logging.debug('Distance: {}cm'.format(dist))
+ if dist<3:
+ self.parent.goalDetected.emit(self.parent.side)
diff --git a/core/player.py b/core/player.py
index 6107fc9f4f519157811e09d080fc4be9442be06e..c539e94457903078abd0dd7dad0610a6da301298 100644
--- a/core/player.py
+++ b/core/player.py
@@ -128,7 +128,7 @@ class Player(QObject):
'''
Retrieves a player's informations from the Ginger API
'''
- response = Ginger.call('badge/{}'.format(rfid))
+ response = Ginger.instance.get('badge/{}'.format(rfid))
if isinstance(response, HTTPStatus):
logging.warn('Request to Ginger failed ({}): returning Guest'.format(response.value))
return PlayerGuest
@@ -138,7 +138,7 @@ class Player(QObject):
return Player._loadFromDB(rfid)
- def displayImg(self, container_widget, *args):
+ def displayImg(self, container_widget):
self.pic_container = container_widget
if self.pic_path.startswith('http'):
diff --git a/devtools.sh b/devtools.sh
index 2d70f73be50c6eca544b22c62ed1b078afabe0d1..54112abe70066fa7f3f6a42c381fcf16324af0c5 100755
--- a/devtools.sh
+++ b/devtools.sh
@@ -63,6 +63,37 @@ case "$1" in
cd ..
python -m Babyfut.babyfut
;;
+ "install")
+ echo "Installing.."
+ echo "** Assuming debian-like environment. This shouldn't be run more than once"
+ echo "** Updating the system to make sure everything is up-to-date."
+ echo ""
+ sudo apt-get update && sudo apt-get upgrade
+
+ echo ""
+ echo "** Installing python3 and python tools"
+ # Sometimes the PYTHONPATH wont be set accordingly for some raspbian distributions
+ # In which case, manually import the right path (/usr/lib/python3/dist-packages) in
+ # the virtual environment's activation script
+ sudo apt-get install -y python3 python3-venv python3-pyqt5 python3-pip qtmultimedia5-examples \
+ pyqt5-dev pyqt5-dev-tools
+
+ echo ""
+ echo "** Setting up the python virtual environment"
+ python3 -m venv ../PyQt5
+ source ../PyQt5/bin/activate
+
+ echo ""
+ echo "** Installing libraries used by the software"
+ pip install pi-rc522 pyautogui Xlib RPi.GPIO request
+
+ echo ""
+ echo "****************************"
+ echo ""
+ echo "Installation done successfully! You may have to source the v-env."
+ echo "Don't forget to download the \"content\" folder from another source."
+ bash ./devtools.sh "allc"
+ ;;
*)
echo "Unknown command \"$1\". See script for available commands."
;;
diff --git a/translations/babyfut_fr.ts b/translations/babyfut_fr.ts
index c6d1947daccf58416102041f037b17e2726cde98..d99990587ed2d1236daf242e585930c83fe2b3c2 100644
--- a/translations/babyfut_fr.ts
+++ b/translations/babyfut_fr.ts
@@ -66,12 +66,12 @@
Stat
-
+
Player 1
Joueur 1
-
+
Player 2
Joueur 2
@@ -91,7 +91,7 @@
Joueur 4
-
+
Congratulations!
Félicitations !
diff --git a/ui/mainwin.py b/ui/mainwin.py
index b63c23ea89896ed7638c59240c4e0c8ec1d82126..11d0d744177bad6325d99b834060628290d96634 100644
--- a/ui/mainwin.py
+++ b/ui/mainwin.py
@@ -80,11 +80,6 @@ class MainWin(QtWidgets.QMainWindow):
for modIdx in modulesIdx:
self.modules[modIdx].other(**msg)
-
- @pyqtSlot(str)
- def rfidHandler(self, rfid):
- side = Side.Left if Settings['app.side']=='left' else Side.Right
- self.dispatchMessage({'rfid': rfid, 'source': side})
def _loadSettings(self):
if Settings['ui.fullscreen']: