Improved error handling

This commit is contained in:
Balthasar Reuter
2018-04-17 22:43:25 +02:00
parent ee80244f69
commit cf9e687102
5 changed files with 71 additions and 31 deletions

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import io import io, logging
from PIL import Image from PIL import Image
@@ -19,6 +19,11 @@ class CameraGphoto2Cffi(Camera):
self.hasPreview = True self.hasPreview = True
self.hasIdle = True self.hasIdle = True
# Avoid output cluttered
logging.basicConfig(
format='%(levelname)s: %(name)s: %(message)s',
level=logging.CRITICAL)
self._setupCamera() self._setupCamera()

View File

@@ -110,6 +110,13 @@ class MessageState(GuiState):
class GreeterState(GuiState):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class PoseState(GuiState): class PoseState(GuiState):
def __init__(self, **kwargs): def __init__(self, **kwargs):

View File

@@ -27,7 +27,7 @@ class Photobooth:
self._pic_dims = PictureDimensions(config, self._cap.getPicture().size) self._pic_dims = PictureDimensions(config, self._cap.getPicture().size)
self._pic_list = PictureList(picture_basename) self._pic_list = PictureList(picture_basename)
self._pose_time = config.getInt('Photobooth', 'pose_time') self._greeter_time = config.getInt('Photobooth', 'greeter_time')
self._countdown_time = config.getInt('Photobooth', 'countdown_time') self._countdown_time = config.getInt('Photobooth', 'countdown_time')
self._display_time = config.getInt('Photobooth', 'display_time') self._display_time = config.getInt('Photobooth', 'display_time')
@@ -53,9 +53,9 @@ class Photobooth:
@property @property
def poseTime(self): def greeterTime(self):
return self._pose_time return self._greeter_time
@property @property
@@ -78,6 +78,9 @@ class Photobooth:
while True: while True:
try: try:
event = recv.recv() event = recv.recv()
if str(event) != 'triggered':
print('Unknown event received: ' + str(event))
raise RuntimeError('Unknown event received', str(event))
except EOFError: except EOFError:
return 1 return 1
else: else:
@@ -121,10 +124,15 @@ class Photobooth:
sleep(1) sleep(1)
def showPose(self):
self._send.send( Gui.PoseState() )
def captureSinglePicture(self): def captureSinglePicture(self):
self.showCounter() self.showCounter()
self.showPose()
return self._cap.getPicture() return self._cap.getPicture()
@@ -147,10 +155,10 @@ class Photobooth:
def trigger(self): def trigger(self):
self._send.send(Gui.PoseState()) self._send.send(Gui.GreeterState())
self.setCameraActive() self.setCameraActive()
sleep(self.poseTime) sleep(self.greeterTime)
img = self.capturePictures() img = self.capturePictures()
img.save(self.getNextFilename(), 'JPEG') img.save(self.getNextFilename(), 'JPEG')
@@ -165,20 +173,29 @@ class Photobooth:
def main_photobooth(config, send, recv): def main_photobooth(config, send, recv):
if config.get('Camera', 'module') == 'python-gphoto2': while True:
from CameraGphoto2 import CameraGphoto2 as Camera try:
elif config.get('Camera', 'module') == 'gphoto2-cffi': if config.get('Camera', 'module') == 'python-gphoto2':
from CameraGphoto2Cffi import CameraGphoto2Cffi as Camera from CameraGphoto2 import CameraGphoto2 as Camera
elif config.get('Camera', 'module') == 'gphoto2-commandline': elif config.get('Camera', 'module') == 'gphoto2-cffi':
from CameraGphoto2CommandLine import CameraGphoto2CommandLine as Camera from CameraGphoto2Cffi import CameraGphoto2Cffi as Camera
elif config.get('Camera', 'module') == 'opencv': elif config.get('Camera', 'module') == 'gphoto2-commandline':
from CameraOpenCV import CameraOpenCV as Camera from CameraGphoto2CommandLine import CameraGphoto2CommandLine as Camera
else: elif config.get('Camera', 'module') == 'opencv':
raise ImportError('Unknown camera module "' + config.get('Camera', 'module') + '"') from CameraOpenCV import CameraOpenCV as Camera
else:
raise ModuleNotFoundError('Unknown camera module "' + config.get('Camera', 'module') + '"')
with Camera() as cap: with Camera() as cap:
photobooth = Photobooth(config, cap) photobooth = Photobooth(config, cap)
return photobooth.run(send, recv) return photobooth.run(send, recv)
except BaseException as e:
send.send( Gui.ErrorState('Camera error', str(e), True) )
event = recv.recv()
if str(event) != 'ack':
print('Unknown event received: ' + str(event))
raise RuntimeError('Unknown event received', str(event))
def run(argv): def run(argv):

View File

@@ -20,6 +20,7 @@ class PyQt5Gui(Gui.Gui):
self._app = QApplication(argv) self._app = QApplication(argv)
self._p = PyQt5MainWindow() self._p = PyQt5MainWindow()
self._lastState = self.showStart
def run(self, send, recv): def run(self, send, recv):
@@ -54,10 +55,16 @@ class PyQt5Gui(Gui.Gui):
if event.key() == Qt.Key_Escape: if event.key() == Qt.Key_Escape:
self.showStart() self.showStart()
elif event.key() == Qt.Key_Space: elif event.key() == Qt.Key_Space:
self._p.handleKeypressEvent = lambda event : None self._p.handleKeypressEvent = self.handleKeypressEventNoTrigger
self._transport.send('triggered') self._transport.send('triggered')
def handleKeypressEventNoTrigger(self, event):
if event.key() == Qt.Key_Escape:
self.showStart()
def handleState(self, state): def handleState(self, state):
if not isinstance(state, Gui.GuiState): if not isinstance(state, Gui.GuiState):
@@ -65,7 +72,7 @@ class PyQt5Gui(Gui.Gui):
if isinstance(state, Gui.IdleState): if isinstance(state, Gui.IdleState):
self.showIdle() self.showIdle()
elif isinstance(state, Gui.PoseState): elif isinstance(state, Gui.GreeterState):
global cfg global cfg
num_pictures = ( cfg.getInt('Picture', 'num_x') * num_pictures = ( cfg.getInt('Picture', 'num_x') *
cfg.getInt('Picture', 'num_y') ) cfg.getInt('Picture', 'num_y') )
@@ -74,6 +81,8 @@ class PyQt5Gui(Gui.Gui):
elif isinstance(state, Gui.PreviewState): elif isinstance(state, Gui.PreviewState):
img = ImageQt.ImageQt(state.picture) img = ImageQt.ImageQt(state.picture)
self._p.setCentralWidget(PyQt5PictureMessage(state.message, img)) self._p.setCentralWidget(PyQt5PictureMessage(state.message, img))
elif isinstance(state, Gui.PoseState):
self._p.setCentralWidget(PyQt5PictureMessage('Pose!'))
elif isinstance(state, Gui.PictureState): elif isinstance(state, Gui.PictureState):
img = ImageQt.ImageQt(state.picture) img = ImageQt.ImageQt(state.picture)
self._p.setCentralWidget(PyQt5PictureMessage('', img)) self._p.setCentralWidget(PyQt5PictureMessage('', img))
@@ -86,18 +95,21 @@ class PyQt5Gui(Gui.Gui):
def showStart(self): def showStart(self):
self._p.handleKeypressEvent = lambda event : None self._p.handleKeypressEvent = lambda event : None
self._lastState = self.showStart
self._p.setCentralWidget(PyQt5Start(self)) self._p.setCentralWidget(PyQt5Start(self))
def showSettings(self): def showSettings(self):
self._p.handleKeypressEvent = lambda event : None self._p.handleKeypressEvent = lambda event : None
self._lastState = self.showSettings
self._p.setCentralWidget(PyQt5Settings(self)) self._p.setCentralWidget(PyQt5Settings(self))
def showIdle(self): def showIdle(self):
self._p.handleKeypressEvent = self.handleKeypressEvent self._p.handleKeypressEvent = self.handleKeypressEvent
self._lastState = self.showIdle
self._p.setCentralWidget(PyQt5PictureMessage('Hit the button!')) self._p.setCentralWidget(PyQt5PictureMessage('Hit the button!'))
@@ -105,7 +117,8 @@ class PyQt5Gui(Gui.Gui):
if QMessageBox.warning(self._p, title,message, QMessageBox.Ok, if QMessageBox.warning(self._p, title,message, QMessageBox.Ok,
QMessageBox.Ok) == QMessageBox.Ok: QMessageBox.Ok) == QMessageBox.Ok:
self.showIdle() self._transport.send('ack')
self._lastState()
class PyQt5Receiver(QThread): class PyQt5Receiver(QThread):
@@ -359,13 +372,13 @@ class PyQt5Settings(QFrame):
self._value_widgets['Photobooth']['show_preview'] = QCheckBox('Show preview while countdown') self._value_widgets['Photobooth']['show_preview'] = QCheckBox('Show preview while countdown')
if cfg.getBool('Photobooth', 'show_preview'): if cfg.getBool('Photobooth', 'show_preview'):
self._value_widgets['Photobooth']['show_preview'].toggle() self._value_widgets['Photobooth']['show_preview'].toggle()
self._value_widgets['Photobooth']['pose_time'] = QLineEdit(cfg.get('Photobooth', 'pose_time')) self._value_widgets['Photobooth']['greeter_time'] = QLineEdit(cfg.get('Photobooth', 'greeter_time'))
self._value_widgets['Photobooth']['countdown_time'] = QLineEdit(cfg.get('Photobooth', 'countdown_time')) self._value_widgets['Photobooth']['countdown_time'] = QLineEdit(cfg.get('Photobooth', 'countdown_time'))
self._value_widgets['Photobooth']['display_time'] = QLineEdit(cfg.get('Photobooth', 'display_time')) self._value_widgets['Photobooth']['display_time'] = QLineEdit(cfg.get('Photobooth', 'display_time'))
layout = QFormLayout() layout = QFormLayout()
layout.addRow(self._value_widgets['Photobooth']['show_preview']) layout.addRow(self._value_widgets['Photobooth']['show_preview'])
layout.addRow(QLabel('Pose time [s]:'), self._value_widgets['Photobooth']['pose_time']) layout.addRow(QLabel('Pose time [s]:'), self._value_widgets['Photobooth']['greeter_time'])
layout.addRow(QLabel('Countdown time [s]:'), self._value_widgets['Photobooth']['countdown_time']) layout.addRow(QLabel('Countdown time [s]:'), self._value_widgets['Photobooth']['countdown_time'])
layout.addRow(QLabel('Display time [s]:'), self._value_widgets['Photobooth']['display_time']) layout.addRow(QLabel('Display time [s]:'), self._value_widgets['Photobooth']['display_time'])
@@ -456,7 +469,7 @@ class PyQt5Settings(QFrame):
cfg.set('Gpio', 'lamp_channel', self._value_widgets['Gpio']['lamp_channel'].text()) cfg.set('Gpio', 'lamp_channel', self._value_widgets['Gpio']['lamp_channel'].text())
cfg.set('Photobooth', 'show_preview', str(self._value_widgets['Photobooth']['show_preview'].isChecked())) cfg.set('Photobooth', 'show_preview', str(self._value_widgets['Photobooth']['show_preview'].isChecked()))
cfg.set('Photobooth', 'pose_time', str(self._value_widgets['Photobooth']['pose_time'].text())) cfg.set('Photobooth', 'greeter_time', str(self._value_widgets['Photobooth']['greeter_time'].text()))
cfg.set('Photobooth', 'countdown_time', str(self._value_widgets['Photobooth']['countdown_time'].text())) cfg.set('Photobooth', 'countdown_time', str(self._value_widgets['Photobooth']['countdown_time'].text()))
cfg.set('Photobooth', 'display_time', str(self._value_widgets['Photobooth']['display_time'].text())) cfg.set('Photobooth', 'display_time', str(self._value_widgets['Photobooth']['display_time'].text()))
@@ -468,8 +481,6 @@ class PyQt5Settings(QFrame):
cfg.set('Picture', 'min_dist_y', self._value_widgets['Picture']['min_dist_y'].text()) cfg.set('Picture', 'min_dist_y', self._value_widgets['Picture']['min_dist_y'].text())
cfg.set('Picture', 'basename', self._value_widgets['Picture']['basename'].text()) cfg.set('Picture', 'basename', self._value_widgets['Picture']['basename'].text())
# wrapper_idx2val = [ 'commandline', 'piggyphoto', 'gphoto2-cffi', '' ]
# cfg.set('Camera', 'module', wrapper_idx2val[self._value_widgets['Camera']['module'].currentIndex()])
cfg.set('Camera', 'module', self._camera_modules[self._value_widgets['Camera']['module'].currentIndex()][0]) cfg.set('Camera', 'module', self._camera_modules[self._value_widgets['Camera']['module'].currentIndex()][0])
cfg.write() cfg.write()

View File

@@ -23,10 +23,10 @@ lamp_channel = 4
[Photobooth] [Photobooth]
# Show preview while posing time (True/False) # Show preview while posing time (True/False)
show_preview = True show_preview = True
# Pose time in seconds (shown before countdown) # Greeter time in seconds (shown before countdown)
pose_time = 3 greeter_time = 3
# Countdown length in seconds (shown before every shot) # Countdown length in seconds (shown before every shot)
countdown_time = 2 countdown_time = 5
# Display time of assembled picture (shown after last shot) # Display time of assembled picture (shown after last shot)
display_time = 5 display_time = 5