Skip to content

Commit b454465

Browse files
committed
I04_1-150: showing message for duplicate puck barcode
1 parent bc9164c commit b454465

File tree

6 files changed

+88
-15
lines changed

6 files changed

+88
-15
lines changed

dls_barcode/camera/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from .camera_switch import CameraSwitch
22
from .camera_scanner import CameraScanner
3+
from .scanner_message import NoNewBarcodeMessage, ScanErrorMessage
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class NoNewBarcodeMessage:
2+
pass
3+
4+
class ScanErrorMessage:
5+
def __init__(self, content):
6+
self._content = content
7+
8+
def content(self):
9+
return self._content

dls_barcode/camera/scanner_worker.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from dls_barcode.datamatrix import DataMatrix
88
from .camera_position import CameraPosition
99
from .plate_overlay import PlateOverlay
10+
from .scanner_message import NoNewBarcodeMessage, ScanErrorMessage
1011

1112
NO_PUCK_TIME = 2
1213

@@ -20,7 +21,7 @@ class ScannerWorker:
2021
"""
2122
def run(self, task_queue, overlay_queue, result_queue, message_queue, kill_queue, config, cam_position):
2223
print("SCANNER start")
23-
self._last_plate_time = time.time()
24+
self._last_puck_time = time.time()
2425

2526
SlotScanner.DEBUG = config.slot_images.value()
2627
SlotScanner.DEBUG_DIR = config.slot_image_directory.value()
@@ -54,8 +55,8 @@ def _process_frame(self, frame, config, overlay_queue, result_queue, message_que
5455
scan_result.print_summary()
5556

5657
if scan_result.success():
57-
# Record the time so we can see how long its been since we last saw a plate
58-
self._last_plate_time = time.time()
58+
# Record the time so we can see how long its been since we last saw a puck
59+
self._last_puck_time = time.time()
5960

6061
plate = scan_result.plate()
6162
if scan_result.any_valid_barcodes():
@@ -64,8 +65,12 @@ def _process_frame(self, frame, config, overlay_queue, result_queue, message_que
6465

6566
if scan_result.any_new_barcodes():
6667
result_queue.put((plate, image))
67-
elif scan_result.error() is not None and (time.time() - self._last_plate_time > NO_PUCK_TIME):
68-
message_queue.put(Message(MessageType.WARNING, scan_result.error(), lifetime=1))
68+
elif scan_result.any_valid_barcodes():
69+
# We have read valid barcodes but they are not new
70+
self._last_puck_time = time.time()
71+
message_queue.put(NoNewBarcodeMessage())
72+
elif scan_result.error() is not None and (time.time() - self._last_puck_time > NO_PUCK_TIME):
73+
message_queue.put(ScanErrorMessage(scan_result.error()))
6974

7075
def _create_scanner(self, cam_position, config):
7176
if cam_position == CameraPosition.SIDE:

dls_barcode/gui/main_window.py

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import multiprocessing
22
import queue
3+
import time
34

45
from PyQt4 import QtGui, QtCore
56

67
from dls_barcode.config import BarcodeConfig, BarcodeConfigDialog
7-
from dls_barcode.camera import CameraScanner, CameraSwitch
8+
from dls_barcode.camera import CameraScanner, CameraSwitch, NoNewBarcodeMessage
89
from dls_util import Beeper
910
from dls_util.file import FileManager
1011
from dls_util.message import MessageType, Message
@@ -14,6 +15,11 @@
1415
from .message_display import MessageDisplay
1516

1617

18+
RESULT_TIMER_PERIOD = 1000 # ms
19+
VIEW_TIMER_PERIOD = 1 # ms
20+
MESSAGE_TIMER_PERIOD = 1 # ms
21+
22+
1723
class DiamondBarcodeMainWindow(QtGui.QMainWindow):
1824
""" Main GUI window for the Barcode Scanner App.
1925
"""
@@ -39,19 +45,20 @@ def __init__(self, config_file):
3945
self._view_queue = multiprocessing.Queue()
4046
self._message_queue = multiprocessing.Queue()
4147
self._initialise_scanner()
48+
self._reset_test_timer()
4249

4350
# Timer that controls how often new scan results are looked for
4451
self._result_timer = QtCore.QTimer()
4552
self._result_timer.timeout.connect(self._read_result_queue)
46-
self._result_timer.start(1000)
53+
self._result_timer.start(RESULT_TIMER_PERIOD)
4754

4855
self._view_timer = QtCore.QTimer()
4956
self._view_timer.timeout.connect(self._read_view_queue)
50-
self._view_timer.start(1)
57+
self._view_timer.start(VIEW_TIMER_PERIOD)
5158

5259
self._message_timer = QtCore.QTimer()
5360
self._message_timer.timeout.connect(self._read_message_queue)
54-
self._message_timer.start(1)
61+
self._message_timer.start(MESSAGE_TIMER_PERIOD)
5562

5663
self._camera_switch.restart_live_capture_from_side()
5764

@@ -195,11 +202,45 @@ def _read_view_queue(self):
195202
def _read_message_queue(self):
196203
if not self._message_queue.empty():
197204
try:
198-
message = self._message_queue.get(False)
199-
self._message_display.display_message(message)
205+
scanner_msg = self._message_queue.get(False)
206+
if self._camera_switch.is_side() and isinstance(scanner_msg, NoNewBarcodeMessage):
207+
if not self._test_timer_is_running():
208+
self._start_test_timer()
209+
elif self._has_test_timer_timeout():
210+
self._message_display.display_message(self._get_duplicate_barcode_message())
211+
else:
212+
self._reset_test_timer()
213+
self._message_display.display_message(self._get_message_from_scanner_msg(scanner_msg))
200214
except queue.Empty:
201215
return
202216

217+
def _get_duplicate_barcode_message(self):
218+
return Message(MessageType.WARNING, "Puck barcode already in database")
219+
220+
def _get_message_from_scanner_msg(self, scanner_msg):
221+
return Message(MessageType.WARNING, scanner_msg.content())
222+
223+
def _get_puck_recorded_message(self):
224+
return Message(MessageType.INFO, "Puck barcode recorded")
225+
226+
def _get_scan_timeout_message(self):
227+
return Message(MessageType.WARNING, "Scan timeout")
228+
229+
def _get_scan_completed_message(self):
230+
return Message(MessageType.INFO, "Scan completed")
231+
232+
def _reset_test_timer(self):
233+
self._test_timer = None
234+
235+
def _start_test_timer(self):
236+
self._test_timer = time.time()
237+
238+
def _test_timer_is_running(self):
239+
return self._test_timer is not None
240+
241+
def _has_test_timer_timeout(self):
242+
return self._test_timer_is_running() and time.time() - self._test_timer > 2*RESULT_TIMER_PERIOD/1000
243+
203244
def _read_result_queue(self):
204245
""" Called every second; read any new results from the scan results queue, store them and display them.
205246
"""
@@ -222,17 +263,19 @@ def _read_side_scan(self):
222263

223264
# Barcode successfully read
224265
Beeper.beep()
225-
print("MAIN: holder barcode recorded")
266+
print("MAIN: puck barcode recorded")
226267
if self._record_table.unique_side_barcode(plate): # if new side barcode
227268
self.original_plate = plate
228269
self._latest_holder_image = holder_image
229-
self._message_display.display_message(Message(MessageType.INFO, "Plate barcode recorded"))
270+
self._message_display.display_message(self._get_puck_recorded_message())
230271
self._camera_switch.restart_live_capture_from_top()
272+
else:
273+
self._message_display.display_message(self._get_duplicate_barcode_message())
231274

232275
def _read_top_scan(self):
233276
if self._result_queue.empty():
234277
if self._camera_switch.is_top_scan_timeout():
235-
self._message_display.display_message(Message(MessageType.INFO, "Scan timeout", lifetime=4))
278+
self._message_display.display_message(self._get_scan_timeout_message())
236279
print("\n*** Scan timeout ***")
237280
self._camera_switch.restart_live_capture_from_side()
238281
return
@@ -248,6 +291,6 @@ def _read_top_scan(self):
248291
# Barcodes successfully read
249292
Beeper.beep()
250293
print("Scan Completed")
251-
self._message_display.display_message(Message(MessageType.INFO, "Scan completed"))
294+
self._message_display.display_message(self._get_scan_completed_message())
252295
self._camera_switch.restart_live_capture_from_side()
253296

dls_util/object_with_lifetime.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ class ObjectWithLifetime:
55
""" Abstract base class. Has a specified lifetime.
66
"""
77
def __init__(self, lifetime):
8+
"""A lifetime of 0 indicates that the object does not expire"""
89
self._lifetime = lifetime
910
self._start_time = time.time()
1011

1112
def has_expired(self):
13+
if self._lifetime == 0:
14+
return False
15+
1216
return (time.time() - self._start_time) > self._lifetime

tests/unit_tests/test_dls_util/test_object_with_lifetime.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,14 @@ def test_object_with_life_greater_than_lifetime_has_expired(self):
2424

2525
# Assert
2626
self.assertTrue(obj.has_expired())
27+
28+
def test_zero_lifetime_does_not_expire(self):
29+
# Arrange
30+
lifetime = 0
31+
32+
# Act
33+
obj = ObjectWithLifetime(lifetime)
34+
time.sleep(lifetime)
35+
36+
# Assert
37+
self.assertFalse(obj.has_expired())

0 commit comments

Comments
 (0)