diff --git a/config/machine_settings/defaults.ini b/config/machine_settings/defaults.ini
index a66eab0..4bdc4ca 100644
--- a/config/machine_settings/defaults.ini
+++ b/config/machine_settings/defaults.ini
@@ -31,7 +31,7 @@ platform: cups
printer:
-[tecna_marposs_provaset_t3]
+[tecna_t3]
address: COM3
baudrate: 115200
diff --git a/simulate.sh b/simulate.sh
index 9afb7ff..867bb63 100755
--- a/simulate.sh
+++ b/simulate.sh
@@ -18,6 +18,7 @@ python -B -u "./src/main.py" \
--no-autotest \
--no-edgetpu \
--no-gpu \
+--panel \
--sim-camera \
--sim-modbus \
--sim-os-label-printer \
diff --git a/src/components/tecna_marposs_provaset_t3.py b/src/components/tecna_marposs_provaset_t3.py
index 63075cf..08e2a67 100644
--- a/src/components/tecna_marposs_provaset_t3.py
+++ b/src/components/tecna_marposs_provaset_t3.py
@@ -105,22 +105,45 @@ class TecnaMarpossProvasetT3(ModbusComponent):
]}
if info["Running test: type of test"] is None:
info.update(self.get_test_results())
- self.start_test()
self.log.debug(str(info))
super()._get([info])
- def start_test(self):
- self.log.info("starting test")
- self.write("Start testing", 1)
+ def start_test(self, table=1):
+ self.log.info(f"starting test table {table!r}")
+ self.write("Start testing", table)
def stop_test(self):
- self.log.warining("stopping test")
+ self.log.warning("stopping test")
self.write("Stop the test in progress", 0)
def get_test_results(self):
+ self.log.info("getting test results")
return {r: self.read(r) for r in [
"Running test: measured leak",
"Running test: calculated leak flow rate",
"Running test: calculate RVP%",
"Running test: result",
]}
+
+ def write_recipe(self, recipe, table=1):
+ # "pressure_ramp": self.pressure_ramp_sb,
+ # "stabilization_cycles": self.stabilization_cycles_sb,
+ recipe = {
+ "Type of test": "LEAK TEST",
+ # "Test flags": recipe.spec[""],
+ "T0 - Pre-filling time": recipe.spec["pre_filling_time"],
+ "P0 - Pre-filling pressure": recipe.spec["pre_filling_pressure"],
+ "T1 - Filling time": recipe.spec["filling_time"],
+ "T2 - Settling time": recipe.spec["settling_time"],
+ "PR%- Lower tolerance on pressure / P- Minimum pressure": recipe.spec["settling_pressure_min_percent"],
+ "PR%+ Superior tolerance on pressure / P+ Pressure max": recipe.spec["settling_pressure_max_percent"],
+ "T3 - Measure time": recipe.spec["test_time"],
+ "Q- Leak limit": recipe.spec["test_pressure_min_delta"],
+ "PREL - Nominal test pressure": recipe.spec["test_pressure"],
+ "Q+ Upper limit": recipe.spec["test_pressure_max_delta"],
+ "FST - discharge time": recipe.spec["flush_time"],
+ "FSL - discharge limit": recipe.spec["flush_pressure"],
+ }
+ self.log.debug(str(recipe))
+ for register, value in recipe.items():
+ self.write(register, value)
diff --git a/src/components/tecna_marposs_provaset_t3_registers.py b/src/components/tecna_marposs_provaset_t3_registers.py
index 08d22f5..c22de06 100644
--- a/src/components/tecna_marposs_provaset_t3_registers.py
+++ b/src/components/tecna_marposs_provaset_t3_registers.py
@@ -56,7 +56,7 @@ registers = {
4: "not used",
5: "BLOCKAGE TEST PASSED",
100: "LEAK TEST FAILED - UPPER LIMIT",
- 101: "LEAK TEST – FAILED ANOMALY",
+ 101: "LEAK TEST - FAILED ANOMALY",
102: "LEAK TEST - MAXIMUM LEAK FAILED",
103: "BURST - BREAKAGE PRESSURE DEFLECTION",
104: "VOLUMETRIC CONTROL - RVP% FAILED",
@@ -65,14 +65,14 @@ registers = {
107: "BLOCKAGE - MAX PRESSURE FAILED",
108: "BLOCKAGE - MIN PRESSURE FAILED",
109: "BURST - MINIMUM PRESSURE FAILED",
- 200: "LEAK TEST FAILED – PR% PRESSURE MINUM",
+ 200: "LEAK TEST FAILED - PR% PRESSURE MINUM",
201: "LEAK TEST FAILED - PR% PRESSURE MAX",
- 202: "LEAK TEST FAILED – P0% PRESSURE MINUM",
+ 202: "LEAK TEST FAILED - P0% PRESSURE MINUM",
203: "LEAK TEST FAILED - P0% PRESSURE MAX",
204: "ERROR - INTERNAL ALARMS",
205: "ERROR - RELATIVE PRESSURE OUT OF RANGE",
206: "ERROR - DIFFERENTIAL PRESSURE OUT OF RANGE",
- 207: "ERROR – PRE-FILLING VALVE NOT OPENED",
+ 207: "ERROR - PRE-FILLING VALVE NOT OPENED",
250: "TEST ABORTED",
}, }],
"Running test: type of test": [47, {"dt": "16bit_uint", "decoding": {
@@ -130,13 +130,20 @@ registers = {
# 0= Only passed
# 1= Only failed
# 2=All
- "AUTOMATION: Marking – driving time": [624, {"dt": "16bit_uint", }],
+ "AUTOMATION: Marking - driving time": [624, {"dt": "16bit_uint", }],
# Format: x.x seconds
- "Type of test": [701, {"dt": "16bit_uint", }],
- # 1=LEAK TEST
- # 2=BLOCKAGE TEST
- # 3=LEAK TEST WITH VOLUME
- # 4=BURST TEST
+ "Selection number of test table on which you intend to work": [700, {"dt": "16bit_uint", }],
+ "Type of test": [701, {"dt": "16bit_uint", "encoding": {
+ "LEAK TEST": 1,
+ "BLOCKAGE TEST": 2,
+ "LEAK TEST WITH VOLUME": 3,
+ "BURST TEST": 4,
+ }, "decoding": {
+ 1: "LEAK TEST",
+ 2: "BLOCKAGE TEST",
+ 3: "LEAK TEST WITH VOLUME",
+ 4: "BURST TEST",
+ }, }],
"Test flags": [702, {"dt": "16bit_uint", }],
# T0/Pr: Phase filling mode T0 0= TIME 1= PRESSURE
# T1/Pr: Phase filling mode T1 0= TIME 1=PRESSURE
@@ -149,39 +156,39 @@ registers = {
# AT: 0=Tare pressure disabled 1=Tare pressure enabled
# HR: 0=Resolution on loss 1 Pa 1=Resolution on loss 0.1 Pa (models with full scale <= 2 bar)
# CH: Selected test channel (2-channel T3P2C model only)
- "T0 – Pre-filling time": [704, {"dt": "16bit_uint", "f": 26, }],
- "P0 – Pre-filling pressure": [705, {"dt": "16bit_uint", "f": 23, }],
+ "T0 - Pre-filling time": [704, {"dt": "16bit_uint", "f": 26, }],
+ "P0 - Pre-filling pressure": [705, {"dt": "16bit_uint", "f": 23, }],
# In order to use a negative (vacuum) value, this parameter must however be written positively, but the P0- bit must
# also be selected in register 702
- "T1 – Filling time": [706, {"dt": "16bit_uint", "f": 26, }],
- "T2 – Settling time": [707, {"dt": "16bit_uint", "f": 26, }],
- "T3 – Measure time": [708, {"dt": "16bit_uint", "f": 26, }],
- "PREL – Nominal test pressure": [709, {"dt": "16bit_uint", "f": 23, }],
+ "T1 - Filling time": [706, {"dt": "16bit_uint", "f": 26, }],
+ "T2 - Settling time": [707, {"dt": "16bit_uint", "f": 26, }],
+ "T3 - Measure time": [708, {"dt": "16bit_uint", "f": 26, }],
+ "PREL - Nominal test pressure": [709, {"dt": "16bit_uint", "f": 23, }],
# To set a negative pressure (vacuum) this parameters must be written in absolute value and then set
# bit Pr- in register 702
- "Pxx Minimum Pressure": [710, {"dt": "16bit_uint", }],
+ "PR%- Lower tolerance on pressure / P- Minimum pressure": [710, {"dt": "16bit_uint", }],
# PR%- Lower tolerance on pressure: LEAK: Format: x.x %
# P- Minimum pressure: BLOCKAGE: Format as indicated in register 23
# PR- Minimum pressure%: BURST: Format x.x%
- "Q + Upper limit": [711, {"dt": "16bit_uint", "f": 22, }],
+ "Q+ Upper limit": [711, {"dt": "16bit_uint", "f": 22, }],
# Format as indicated in the register 22
"Q- Leak limit": [712, {"dt": "16bit_uint", "f": 22, }],
# Format as indicated in the register 22
- "FST –discharge time": [713, {"dt": "16bit_uint", "f": 26, }],
+ "FST - discharge time": [713, {"dt": "16bit_uint", "f": 26, }],
# Format as indicated in the register 26
- "VP – Equivalent volume": [714, {"dt": "16bit_uint", "f": 25, }],
+ "VP - Equivalent volume": [714, {"dt": "16bit_uint", "f": 25, }],
# Format as indicated in the register 25
"P% Pressure tolerance": [717, {"dt": "16bit_uint", }],
# BLOCKAGE: Format x.x %
- "PB – Minimum burst pressure": [743, {"dt": "16bit_uint", "f": 23, }],
+ "PB - Minimum burst pressure": [743, {"dt": "16bit_uint", "f": 23, }],
# BURST: Format as indicated in the register 23
- "BD – Delta burst": [744, {"dt": "16bit_uint", "f": 23, }],
+ "BD - Delta burst": [744, {"dt": "16bit_uint", "f": 23, }],
# BURST: Format as indicated in the register 23
- "FSL – discharge limit": [745, {"dt": "16bit_uint", "f": 23, }],
+ "FSL - discharge limit": [745, {"dt": "16bit_uint", "f": 23, }],
# Format as indicated in the register 23
- "PR% + Superior tolerance on pressure": [747, {"dt": "16bit_uint", }],
- # LEAK: Format: x.x %
- # P + Pressure max BURST: Format as indicated in the register 23
+ "PR%+ Superior tolerance on pressure / P+ Pressure max": [747, {"dt": "16bit_uint", }],
+ # PR% + Superior tolerance on pressure: LEAK: Format: x.x %
+ # P + Pressure max: BURST: Format as indicated in the register 23
"RVP%: volumetric ratio": [750, {"dt": "16bit_uint", }],
# VOLUME+LEAK: Format x.xx (from 0.00 to 649.99)
"RVP%: max tolerance": [751, {"dt": "16bit_uint", }],
diff --git a/src/lib/db/__init__.py b/src/lib/db/__init__.py
index 6d8ae33..6f64acf 100644
--- a/src/lib/db/__init__.py
+++ b/src/lib/db/__init__.py
@@ -64,24 +64,26 @@ Recipes.replace(id=0, name="TEST", spec={
"client": "TEST_CLIENT",
"part_number": "TEST_PART_NUMBER",
"station": "TEST_STATION",
- # pressure
- "pressure_min": 0,
- "pressure_test": 1,
- "pressure_max": 2,
- "pressure_ramp": 3,
- # test
- "cleaning_time": 4,
- "tolerance": 5,
- "test_duration": 6,
- "flush_duration": 7,
- # stabilizarion
- "stabilization_time": 8,
- "stabilization_level_min": 9,
- "stabilization_level_max": 10,
- "stabilization_settling_time": 11,
- "stabilization_cycles": 12,
- # description
"description": "TEST_DESCRIPTION",
+ # pre-filling
+ "pre_filling_time": 5,
+ "pre_filling_pressure": 3000,
+ # filling
+ "filling_time": 5,
+ "settling_time": 10,
+ "settling_pressure_min_percent": 20,
+ "settling_pressure_max_percent": 20,
+ # test
+ "test_time": 20,
+ "test_pressure_min_delta": 3.00,
+ "test_pressure": 3000,
+ "test_pressure_max_delta": 0.25,
+ "cycles": 1,
+ # flush
+ "flush_time": 2,
+ "flush_pressure": 5,
+ # vision
+ "vision_recipe": 0,
}, archived=False).execute()
if True:
diff --git a/src/main.py b/src/main.py
index 3503712..45f326b 100644
--- a/src/main.py
+++ b/src/main.py
@@ -84,7 +84,7 @@ try:
"label_printer": {"c": Os_Label_Printer, "t": False},
"neo_pixels": {"c": NeoPixels, "t": False},
"remote_api": {"c": RemoteAPI, "k": {"main": self}},
- "tecna_marposs_provaset_t3": {"c": TecnaMarpossProvasetT3},
+ "tecna_t3": {"c": TecnaMarpossProvasetT3, "k": {"paused": True}},
"vision_saver": {"c": VisionSaver, "t": False},
"vision": {"c": Vision, "k": {"paused": True}},
}
diff --git a/src/ui/__init__.py b/src/ui/__init__.py
index 2153c8f..8960c4a 100644
--- a/src/ui/__init__.py
+++ b/src/ui/__init__.py
@@ -14,6 +14,8 @@ from .test import Test
from .test_admin_permission import Test_Admin_Permission
from .test_autotest import Test_Autotest
from .test_home import Test_Home
+from .test_leak import Test_Leak
+from .test_test import Test_Test
from .test_vision import Test_Vision
from .users_management import Users_Management
from .widget import Widget
diff --git a/src/ui/dialog/dialog.py b/src/ui/dialog/dialog.py
index a38fa38..6f5ebcc 100644
--- a/src/ui/dialog/dialog.py
+++ b/src/ui/dialog/dialog.py
@@ -12,8 +12,8 @@ dialogs = {}
class Dialog(QDialog):
_closing = pyqtSignal()
- def __init__(self):
- super().__init__()
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
global dialogs
dialogs[id(self)] = self
self.setAttribute(Qt.WA_DeleteOnClose)
diff --git a/src/ui/recipe_editor/recipe_editor.py b/src/ui/recipe_editor/recipe_editor.py
index a584f82..66b1bc0 100644
--- a/src/ui/recipe_editor/recipe_editor.py
+++ b/src/ui/recipe_editor/recipe_editor.py
@@ -1,5 +1,5 @@
from PyQt5.QtWidgets import (QCheckBox, QComboBox, QDoubleSpinBox, QLineEdit,
- QRadioButton, QSpinBox, QPlainTextEdit)
+ QPlainTextEdit, QRadioButton, QSpinBox)
from ui.widget import Widget
@@ -11,26 +11,26 @@ class Recipe_Editor(Widget):
"client": self.client_le,
"part_number": self.part_number_le,
"station": self.station_le,
- # pressure
- "pressure_min": self.pressure_min_sb,
- "pressure_test": self.pressure_test_sb,
- "pressure_max": self.pressure_max_sb,
- "pressure_ramp": self.pressure_ramp_sb,
+ "description": self.description_pte,
+ # pre-filling
+ "pre_filling_time": self.pre_filling_time_sb,
+ "pre_filling_pressure": self.pre_filling_pressure_sb,
+ # filling
+ "filling_time": self.filling_time_sb,
+ "settling_time": self.settling_time_sb,
+ "settling_pressure_min_percent": self.settling_pressure_min_percent_sb,
+ "settling_pressure_max_percent": self.settling_pressure_max_percent_sb,
# test
- "cleaning_time": self.cleaning_time_sb,
- "tolerance": self.tolerance_sb,
- "test_duration": self.test_duration_sb,
- "flush_duration": self.flush_duration_sb,
+ "test_time": self.test_time_sb,
+ "test_pressure_min_delta": self.test_pressure_min_delta_sb,
+ "test_pressure": self.test_pressure_sb,
+ "test_pressure_max_delta": self.test_pressure_max_delta_sb,
+ "cycles": self.cycles_sb,
+ # flush
+ "flush_time": self.flush_time_sb,
+ "flush_pressure": self.flush_pressure_sb,
# vision
"vision_recipe": self.vision_recipe_cb,
- # stabilizarion
- "stabilization_time": self.stabilization_time_sb,
- "stabilization_level_min": self.stabilization_level_min_sb,
- "stabilization_level_max": self.stabilization_level_max_sb,
- "stabilization_settling_time": self.stabilization_settling_time_sb,
- "stabilization_cycles": self.stabilization_cycles_sb,
- # description
- "description": self.description_pte,
}
def set_readonly(self, readonly):
diff --git a/src/ui/recipe_editor/recipe_editor.ui b/src/ui/recipe_editor/recipe_editor.ui
index 222a36e..d8a3016 100644
--- a/src/ui/recipe_editor/recipe_editor.ui
+++ b/src/ui/recipe_editor/recipe_editor.ui
@@ -6,66 +6,42 @@
0
0
- 494
- 733
+ 845
+ 696
- -
-
-
- Descrizione
-
-
-
-
-
-
-
-
-
-
- Test
+ Pre-Riempimento
-
-
-
-
-
-
-
- -
-
-
- Tempo di prova
+
+
+ 9999
- -
-
-
- Tempo di scarico
-
-
-
- -
-
-
-
-
+
+
+ 9999
+
+
-
- Tempo di pulizia
+ Tempo
-
- bar
+ mbar
@@ -76,31 +52,290 @@
- -
-
-
- s
-
-
-
- -
-
-
- s
-
-
-
-
- Tolleranza
+ Pressione
- -
+
-
+
+
+ Riempimento
+
+
+
-
+
+
+ Soglia min
+
+
+
+ -
+
+
+ Tempo
+
+
+
+ -
+
+
+ s
+
+
+
+ -
+
+
+ 100
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ Soglia max
+
+
+
+ -
+
+
+ 100
+
+
+
+ -
+
+
+ %
+
+
+
+ -
+
+
+ %
+
+
+
+ -
+
+
+ Assestamento
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ s
+
+
+
+
+
+
+ -
+
+
+ Test
+
+
+
-
+
+
+ Cicli
+
+
+
+ -
+
+
+ 0
+
+
+ 9999
+
+
+
+ -
+
+
+ s
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ mbar
+
+
+
+ -
+
+
+ mbar
+
+
+
+ -
+
+
+ Delta min
+
+
+
+ -
+
+
+ Delta max
+
+
+
+ -
+
+
+ Tempo
+
+
+
+ -
+
+
+ mbar
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ Pressione
+
+
+
+ -
+
+
+ 9999
+
+
+
+
+
+
+ -
+
+
+ Scarico
+
+
+
-
+
+
+ Tempo
+
+
+
+ -
+
+
+ Pressione
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ s
+
+
+
+ -
+
+
+ mbar
+
+
+
+
+
+
+ -
+
+
+ Visione
+
+
+
-
+
+
+ Ricetta visione
+
+
+
+ -
+
+
+
+
+
+ -
Ricetta
@@ -120,12 +355,6 @@
- -
-
-
- -
-
-
-
@@ -133,191 +362,26 @@
- -
-
-
-
-
-
- -
-
-
- Stabilizzazione
-
-
-
-
-
-
- Soglia max
-
-
-
- -
-
-
- Soglia min
-
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
+
-
-
-
- -
-
-
- Tempo assestamento
-
-
-
- -
-
-
- Numero di cicli
-
-
-
- -
-
-
- Tempo
-
-
-
- -
-
-
- s
-
-
-
- -
-
-
- %
-
-
-
- -
-
-
- %
-
-
-
- -
-
-
- s
-
-
-
-
-
-
- -
-
-
- Pressione
-
-
-
-
-
-
- -
-
-
- Min
-
-
-
- -
-
-
- Max
-
-
-
- -
-
-
- -
-
-
- bar
-
-
-
- -
-
-
- -
-
-
- -
-
-
- Test
-
-
-
- -
-
-
- bar
-
-
-
- -
-
-
- Rampa di salita
-
-
-
- -
-
-
- bar
-
-
-
- -
-
-
- bar/min
-
-
-
-
-
-
- -
-
-
- Visione
-
-
-
-
-
-
- Ricetta visione
-
-
+
-
-
+
+
+ -
+
+
+ Descrizione
+
+
+
-
+
+
+
+
diff --git a/src/ui/test/test.py b/src/ui/test/test.py
index 36789bd..612252d 100755
--- a/src/ui/test/test.py
+++ b/src/ui/test/test.py
@@ -9,6 +9,7 @@ from ui.helpers import replace_widget
from ui.recipe_selection import Recipe_Selection
from ui.test_assembly import Test_Assembly
from ui.test_autotest import Test_Autotest
+from ui.test_leak import Test_Leak
from ui.test_vision import Test_Vision
from ui.widget import Widget
@@ -39,13 +40,13 @@ class Test(Widget):
"done": Test_Assembly(self.select_step_img("success"), u"COLLAUDO COMPLETATO - RIMUOVERE IL SENSORE"),
"emergency": Test_Assembly(self.select_step_img("reset_emergency"), u"EMERGENZA INTERVENUTA - RIPRISTINARE PULSANTE E SELEZIONARE \"RESET EMERGENZA\" DAL MEN\u00d9 \"STRUMENTI\""),
"fail": Test_Assembly(self.select_step_img("fail"), u"CICLO INTERROTTO - RIMUOVERE IL SENSORE"),
+ "run_test": Test_Assembly(self.select_step_img("wait"), u"ESECUZIONE TEST IN CORSO - ATTENDERE", Test_Leak(components=self.components, recipe=self.recipe)),
"select_recipe": Test_Assembly(None, u"SELEZIONARE IL CODICE DA COLLAUDARE", Recipe_Selection()),
- "vision": Test_Assembly(None, u"ESEGUIRE PROCEDURA DI AUTOTEST", Test_Vision(self.components, None)),
+ "vision": Test_Assembly(None, u"ESEGUIRE PROCEDURA DI AUTOTEST", Test_Vision(components=self.components, recipe=self.recipe)),
"wait": Test_Assembly(self.select_step_img("wait"), u"ATTENDERE - PAUSA INTER CICLO"),
}
- self.cycle_loop = ["vision", "done", "wait"]
+ self.cycle_loop = ["run_test", "vision", "done", "wait"]
self.cycle_index = -1
- self.cycle_changing_state = False
# SETUP AUTOTEST
self.autotest_request = False
if "--no-autotest" not in sys.argv:
@@ -54,23 +55,25 @@ class Test(Widget):
else:
self.autotest_period = None
# INIT TEST DATA
- self.data = None
+ self.data = {}
# INIT PIECES COUNTER ([pieces_ok, pieces_failed])
self.pieces = [0, 0]
# CONNECT CYCLE CONTROLS
self.cancel_b.clicked.connect(self.fail_cycle)
self.change_recipe_b.clicked.connect(self.change_recipe)
for w in self.cycle_states.values():
- if hasattr(w, "ko"):
- w.ko.connect(self.fail_cycle)
if hasattr(w, "ok"):
# custom ok handlers should call next again
if type(w.widget) is Recipe_Selection:
w.ok.connect(self.set_recipe)
+ elif type(w.widget) is Test_Leak:
+ w.ok.connect(self.set_leak)
elif type(w.widget) is Test_Vision:
w.ok.connect(self.set_vision)
else:
w.ok.connect(self.next)
+ if hasattr(w, "ko"):
+ w.ko.connect(self.fail_cycle)
# TESTING
if "--test" in sys.argv:
self.testing = True
@@ -78,6 +81,9 @@ class Test(Widget):
self.testing = False
# /TESTING
# START CYCLE
+ self.next_timer = QTimer()
+ self.next_timer.setSingleShot(True)
+ self.next_timer.timeout.connect(self.next)
self.next()
def refresh_time(self, init=False):
@@ -113,90 +119,6 @@ class Test(Widget):
def setCentralWidget(self, widget):
replace_widget(self, "centralWidget", widget)
- # def check_next(self, interpreted):
- # self.disconnect(self.watched)
- # if "digital_io" in interpreted:
- # if interpreted["digital_io"]["emergency"] is True and self.cycle_state != "emergency":
- # self.cycle_state = "emergency"
- # self.next()
- # elif interpreted["digital_io"]["emergency"] is False and self.cycle_state == "emergency" and self.is_first_cycle_time:
- # self.is_first_cycle_time = False
- # # reset cycle
- # if self.recipe is None:
- # self.cycle_state = -1 # go to recipe selection
- # else:
- # self.cycle_state = 0 # skip recipe selection
- # self.next(fail=True)
- # if type(self.centralWidget()) is not Test_Autotest: # IGNORE DURING AUTOTEST
- # if self.cycle_state == 1: # WAIT FOR PIECE PRESENCE
- # if self.testing is True and self.is_first_cycle_time:
- # self.bench.inputs["io"].set_bit(*self.bench.parsers["digital_io"].presence1, True)
- # self.bench.inputs["io"].set_bit(*self.bench.parsers["digital_io"].presence2, True)
- # # /TESTING
- # if self.is_first_cycle_time:
- # self.is_first_cycle_time = False
- # log_msg("cycle state:", self.cycle_state, "done", msg_type="test")
- # if "digital_io" in interpreted and interpreted["digital_io"]["presence1"] and interpreted["digital_io"]["presence2"]:
- # self.bench.parsers["digital_io"].handler({"lock": True})
- # self.next()
- # elif self.cycle_state == 2: # PIECE INSERTED, LOCK PIECE AFTER DELAY
- # if self.is_first_cycle_time:
- # self.is_first_cycle_time = False
- # log_msg("cycle state:", self.cycle_state, "done", msg_type="test")
- # self.timer.start(2000)
- # elif self.cycle_state == 4: # CAMERA TEST & BARCODE READ DONE, START ASSEMBLY PHASE
- # if self.is_first_cycle_time:
- # self.is_first_cycle_time = False
- # log_msg("cycle state:", self.cycle_state, "done", msg_type="test")
- # self.timer.start(2000)
- # elif self.cycle_state == 5: # WAIT FOR SCREWDRIVER COUNTS
- # if self.is_first_cycle_time and self.bench.parsers["pick_to_light"].request is None:
- # self.bench.parsers["pick_to_light"].handler({
- # "vtfe10": self.recipe.vtfe10,
- # "vtfe11": self.recipe.vtfe11,
- # "vtfe13": self.recipe.vtfe13,
- # })
- # log_msg("SCREWDRIVER ENABLE", msg_type="test")
- # elif "pick_to_light" in interpreted and interpreted["pick_to_light"] is not None:
- # screws = [interpreted["pick_to_light"][k] for k in ["vtfe10", "vtfe11", "vtfe13"]]
- # needed = [self.bench.parsers["pick_to_light"].request[k] for k in ["vtfe10", "vtfe11", "vtfe13"]]
- # done = all([screwed >= requested for screwed, requested in zip(screws, needed)])
- # self.screw_text(screws)
- # if self.is_first_cycle_time and done:
- # self.is_first_cycle_time = False
- # log_msg("cycle state:", self.cycle_state, "done", msg_type="test")
- # self.bench.parsers["pick_to_light"].handler(None)
- # self.screw_text([0, 0, 0])
- # self.bench.parsers["digital_io"].handler({"lock": False})
- # self.next()
- # elif self.cycle_state == 6:
- # # TESTING
- # if self.testing is True:
- # self.bench.inputs["io"].set_bit(*self.bench.parsers["digital_io"].presence1, False)
- # self.bench.inputs["io"].set_bit(*self.bench.parsers["digital_io"].presence2, False)
- # # /TESTING
- # if not self.is_done:
- # self.is_done = True
- # self.done(True)
- # if self.is_done and "digital_io" in interpreted and not interpreted["digital_io"]["presence1"] and not interpreted["digital_io"]["presence2"] and self.is_first_cycle_time:
- # self.is_first_cycle_time = False
- # log_msg("cycle state:", self.cycle_state, "done", msg_type="test")
- # if self.skip:
- # # reset cycle
- # self.cycle_state = 0 # skip recipe selection
- # self.skip = False
- # self.next()
- # else:
- # self.timer.start(2000)
- # elif self.cycle_state == 7: # WAITING BEFORE NEW CYCLE
- # if self.is_first_cycle_time:
- # self.is_first_cycle_time = False
- # log_msg("cycle state:", self.cycle_state, "wait", msg_type="test")
- # # reset cycle
- # self.cycle_state = 0 # skip recipe selection
- # self.timer.start(6000)
- # self.watched = self.bench.interpreter.update.connect(self.check_next)
-
def request_autotest(self, reason): # you can cancel the request calling request_autotest(False)
self.log.info(f"cycle request autotest: reason: {reason!r} autotest_request: {self.autotest_request!r}")
if reason == "init":
@@ -219,11 +141,10 @@ class Test(Widget):
if action == "change_recipe":
self.log.info(f"cycle next: action: {action!r}")
self.set_recipe(recipe=None)
- self.cycle_changing_state = True
self.cycle_state = "select_recipe"
self.cycle_index = -1
# RESET TEST DATA
- self.data = None
+ self.data.clear()
elif action == "fail":
self.log.info(f"cycle next: action: {action!r}")
if self.cycle_state in self.cycle_loop:
@@ -231,32 +152,29 @@ class Test(Widget):
# COUNT FAIL
self.pieces[1] += 1
# FAIL AND RESTART TEST
- self.cycle_changing_state = True
self.cycle_state = "fail"
self.cycle_index = -1
# RESET TEST DATA
- self.data = None
+ self.data.clear()
elif action is not None:
raise NotImplementedError(f"cycle next: action {action!r} is not a valid action")
# if action did not set the next cycle_state
# set next cycle_state normally
- if not self.cycle_changing_state:
- self.cycle_changing_state = True
- if self.recipe is None:
- # if recipe not set: select_recipe
- self.cycle_state = "select_recipe"
+ if self.recipe is None:
+ # if recipe not set: select_recipe
+ self.cycle_state = "select_recipe"
+ else:
+ if self.cycle_index == -1 and self.autotest_request is not False:
+ # if cycle_loop is not started or has ended
+ # and autotest was requested
+ self.autotest_request = False
+ self.cycle_state = "autotest"
+ if self.autotest_period is not None: # reset periodic autotest timer
+ self.time_timer.start(self.autotest_period)
else:
- if self.cycle_index == -1 and self.autotest_request is not False:
- # if cycle_loop is not started or has ended
- # and autotest was requested
- self.autotest_request = False
- self.cycle_state = "autotest"
- if self.autotest_period is not None: # reset periodic autotest timer
- self.time_timer.start(self.autotest_period)
- else:
- # goto next step in cycle_loop
- self.cycle_index = (self.cycle_index + 1) % len(self.cycle_loop)
- self.cycle_state = self.cycle_loop[self.cycle_index]
+ # goto next step in cycle_loop
+ self.cycle_index = (self.cycle_index + 1) % len(self.cycle_loop)
+ self.cycle_state = self.cycle_loop[self.cycle_index]
# enable/disable cycle controls
self.change_recipe_b.setEnabled(self.recipe is not None)
self.cancel_b.setEnabled(self.cycle_state not in {
@@ -268,16 +186,18 @@ class Test(Widget):
self.log.info(f"cycle next: next cycle_state: {self.cycle_state!r}")
# INIT TEST DATA IF STARTING CYCLE LOOP
if self.cycle_index == 0:
- self.data = {}
- if self.cycle_state == "done":
- self.done()
+ self.data.clear()
w = self.cycle_states[self.cycle_state]
if hasattr(w, "start"):
- w.start()
+ w.start(recipe=self.recipe)
+ self.setCentralWidget(w)
+ if self.cycle_state == "done":
+ self.done()
+ self.next_timer.start(2000)
+ elif self.cycle_state == "wait":
+ self.next_timer.start(6000)
# UPDATE PIECES DISPLAY
self.pieces_count_l.setText(f"{self.pieces[0]} OK / {self.pieces[1]} NOK / {sum(self.pieces)} TOT")
- self.setCentralWidget(w)
- self.cycle_changing_state = False
def set_recipe(self, recipe=None):
self.recipe = recipe
@@ -296,7 +216,13 @@ class Test(Widget):
self.data["ok"] = self.data.get("ok", True) and self.data["vision"].get("ok", False)
self.next()
- def done(self, ok=False):
+ def set_leak(self, leak=None):
+ self.data["leak"] = leak
+ self.data["overridden"] = self.data.get("overridden", False) or self.data["leak"].get("overridden", False)
+ self.data["ok"] = self.data.get("ok", True) and self.data["leak"].get("ok", False)
+ self.next()
+
+ def done(self, ok=False, next=False):
self.log.info("cycle done")
archived = Archive.archive(self.recipe, self.data, ok and self.data["ok"], overridden=self.data["overridden"])
self.log.info(f"cycle archived locally: {archived!r}")
diff --git a/src/ui/test_leak/__init__.py b/src/ui/test_leak/__init__.py
new file mode 100644
index 0000000..cf34f7f
--- /dev/null
+++ b/src/ui/test_leak/__init__.py
@@ -0,0 +1 @@
+from .test_leak import Test_Leak
diff --git a/src/ui/test_leak/test_leak.py b/src/ui/test_leak/test_leak.py
new file mode 100644
index 0000000..01a73d0
--- /dev/null
+++ b/src/ui/test_leak/test_leak.py
@@ -0,0 +1,55 @@
+from ui.test_test import Test_Test
+
+
+class Test_Leak(Test_Test):
+ def start(self, recipe=None):
+ super().start(recipe=recipe)
+ # setup test loop
+ self.components["tecna_t3"].write_recipe(self.recipe)
+ self.get_connection = self.components["tecna_t3"].out.connect(self.get)
+ self.components["tecna_t3"].resume()
+ self.components["tecna_t3"].start_test()
+
+ def stop(self):
+ # disable tes loop
+ self.components["tecna_t3"].stop_test()
+ self.components["tecna_t3"].pause()
+ self.disconnect(self.get_connection)
+ super().stop()
+
+ def get(self, data=None, override=False):
+ if self.ok_timer.isActive():
+ # avoid proccessing if vision was completed
+ return
+ if data is None or data[-1] is None:
+ super().get(None, override=override)
+ return
+ data = data[-1]
+ super().get([{
+ "time": data.get("time", None),
+ "results": {
+ "ok": type(data["tecna_t3"]["Running test: result"]) is str and "passed" in data["tecna_t3"]["Running test: result"].lower(),
+ "result": data["tecna_t3"]["Running test: result"],
+ "data": data["tecna_t3"],
+ },
+ }], override=override)
+
+ def visualize(self, data=None):
+ if data is None:
+ data = {}
+ d = data.get("results", {}).get("data", {})
+ for register, label in {
+ "Instrument status: active phase": self.test_phase_l,
+ "Test circuit pressure, in real time": self.circuit_pressure_l,
+ "Measured leak, in real time": self.leak_l,
+ "Regulated pressure, in real time": self.regulated_pressure_l,
+ # "Active alarm flags": self._l,
+ "Running test: type of test": self.test_type_l,
+ "Testing in progress: progressive sequence index": self.sequence_index_l,
+ }.items():
+ label.setText(str(d.get(register, "-")))
+ super().visualize(data)
+
+ def save_last(self):
+ if self.last is None:
+ return
diff --git a/src/ui/test_leak/test_leak.ui b/src/ui/test_leak/test_leak.ui
new file mode 100644
index 0000000..8ee1332
--- /dev/null
+++ b/src/ui/test_leak/test_leak.ui
@@ -0,0 +1,230 @@
+
+
+ Leak
+
+
+
+ 0
+ 0
+ 322
+ 329
+
+
+
+ Leak
+
+
+ -
+
+
+ Test sequence index:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Regulated pressure:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Status:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Leak:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ Circuit pressure:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ SALVA IMMAGINE
+
+
+
+ -
+
+
+ Instrument status:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Type of test:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Risultato
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ %v / %m
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 32
+ 32
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ FORZA ACCETTAZIONE
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ -
+
+
+
+ -
+
+
+ Test phase
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+
+
diff --git a/src/ui/test_test/__init__.py b/src/ui/test_test/__init__.py
new file mode 100644
index 0000000..3fe33a6
--- /dev/null
+++ b/src/ui/test_test/__init__.py
@@ -0,0 +1 @@
+from .test_test import Test_Test
diff --git a/src/ui/test_test/test_test.py b/src/ui/test_test/test_test.py
new file mode 100644
index 0000000..19e4220
--- /dev/null
+++ b/src/ui/test_test/test_test.py
@@ -0,0 +1,167 @@
+import sys
+
+from lib.helpers import timing
+from PyQt5.QtCore import Qt, QTimer, pyqtSignal
+from PyQt5.QtGui import QColor, QPalette, QPixmap
+from ui import Dialog
+from ui.test_admin_permission import Test_Admin_Permission
+from ui.widget import Widget
+
+
+class Test_Test(Widget):
+ ok = pyqtSignal(dict)
+ ko = pyqtSignal(dict)
+
+ def __init__(self, components=None, recipe=None):
+ super().__init__()
+ self.components = components
+ self.recipe = recipe
+ # setup variables
+ self.ok_counter = 0
+ self.ok_counter_limit = 1
+ # setup controls
+ self.ok_timer = QTimer()
+ self.ok_timer.setSingleShot(True)
+ self.ok_timer.setInterval(2000)
+ self.ok_timer.timeout.connect(self.emit_ok)
+ # setup save frame button
+ self.last = None
+ self.save_b.setEnabled(False)
+ self.save_b.clicked.connect(self.save_last)
+ # setup override
+ self.admin_challenged = False
+ self.override_b.clicked.connect(self.override)
+ self.override_b.setEnabled(True)
+ # setup vision staus gui
+ self.status_imgs_full = {
+ True: QPixmap("src/ui/imgs/success.png"),
+ "": QPixmap("src/ui/imgs/neo.ico"),
+ "warning": QPixmap("src/ui/imgs/warning.png"),
+ False: QPixmap("src/ui/imgs/fail.png"),
+ None: QPixmap("src/ui/imgs/wait.png"),
+ }
+ self.status_imgs_small = {k: i.scaled(32, 32, Qt.KeepAspectRatio, Qt.SmoothTransformation) for k, i in self.status_imgs_full.items()}
+ self.status_palettes = {
+ True: QPalette(),
+ "": QPalette(),
+ "warning": QPalette(),
+ False: QPalette(),
+ None: QPalette(),
+ }
+ self.status_palettes[True].setColor(QPalette.Base, Qt.green)
+ self.status_palettes[False].setColor(QPalette.Base, Qt.red)
+ self.status_palettes["warning"].setColor(QPalette.Base, QColor(255, 165, 0))
+ self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0))
+ self.visualize()
+
+ def start(self, recipe=None):
+ self.recipe = recipe
+ self.visualize()
+ # start test
+ self.start_time = timing()
+ # TESTING
+ if "--test" in sys.argv:
+ if hasattr(self, "_test_overridden_test_"):
+ del self._test_overridden_test_
+ # /TESTING
+
+ def stop(self):
+ pass
+
+ def get(self, data=None, override=False):
+ if self.ok_timer.isActive():
+ # avoid proccessing if test was completed
+ return
+ if data is None:
+ if self.last is not None:
+ data = self.last
+ else:
+ data = {}
+ else:
+ data = data[-1]
+ if not override:
+ result_ok = data.get("results", {}).get("ok", False)
+ else:
+ result_ok = True
+ self.last = {
+ **data,
+ "overridden": override,
+ "duration": timing() - self.start_time,
+ "ok": result_ok,
+ }
+ if not override:
+ if result_ok is True:
+ self.ok_counter += 1
+ else:
+ self.ok_counter = 0
+ else:
+ self.ok_counter = self.ok_counter_limit
+ # check if completed
+ if self.ok_counter >= self.ok_counter_limit:
+ self.stop()
+ self.ok_timer.start()
+ self.visualize(self.last)
+ # TESTING
+ if "--test" in sys.argv:
+ if not hasattr(self, "_test_overridden_test_"):
+ self._test_overridden_test_ = True
+ self.override_b.click()
+ # /TESTING
+
+ def visualize(self, data=None, img=None):
+ if data is None:
+ data = {}
+ overridden = data.get("overridden", False)
+ results = data.get("results", None)
+ self.save_b.setEnabled(self.last is not None)
+ if overridden:
+ self.state_l.setPixmap(self.status_imgs_small["warning"])
+ elif results is None:
+ self.state_l.setPixmap(self.status_imgs_small[None])
+ elif results.get("ok", False) is True:
+ self.state_l.setPixmap(self.status_imgs_small[True])
+ else:
+ self.state_l.setPixmap(self.status_imgs_small[False])
+ self.ok_counter_pb.setMaximum(self.ok_counter_limit)
+ self.ok_counter_pb.setValue(min(self.ok_counter, self.ok_counter_limit))
+ if self.ok_counter >= self.ok_counter_limit:
+ self.ok_counter_pb.setPalette(self.status_palettes[True])
+ else:
+ self.ok_counter_pb.setPalette(self.status_palettes[False])
+ if img is None:
+ if overridden:
+ self.img = self.status_imgs_full["warning"]
+ else:
+ self.img = self.status_imgs_full[None]
+ else:
+ self.img = img
+ self.resizeEvent()
+
+ def save_last(self):
+ if self.last is None:
+ return
+
+ def resizeEvent(self, event=None):
+ self.img_l.setPixmap(self.img.scaled(self.img_l.width(), self.img_l.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
+
+ def challenge_admin(self, info):
+ if not self.admin_challenged:
+ d = Dialog(parent=self)
+ d.setCentralWidget(Test_Admin_Permission(info))
+ d.setModal(True)
+ d.show()
+ r = d.exec()
+ if r == d.Accepted:
+ self.admin_challenged = True
+ elif r == d.Rejected:
+ self.admin_challenged ^= False
+ else:
+ raise AssertionError("Bad admin challenge dialog return code")
+ return self.admin_challenged
+
+ def override(self):
+ if self.challenge_admin("Si sta tentando di bypassare il test"):
+ self.get(override=True)
+
+ def emit_ok(self):
+ self.ok.emit(self.last)
diff --git a/src/ui/test_test/test_test.ui b/src/ui/test_test/test_test.ui
new file mode 100644
index 0000000..a3c4252
--- /dev/null
+++ b/src/ui/test_test/test_test.ui
@@ -0,0 +1,110 @@
+
+
+ Test
+
+
+
+ 0
+ 0
+ 618
+ 835
+
+
+
+ Test
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ FORZA ACCETTAZIONE
+
+
+
+ -
+
+
+ Risultato
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ 50
+
+
+ %v / %m
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 32
+ 32
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 600
+ 700
+
+
+
+ -
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ SALVA IMMAGINE
+
+
+
+
+
+
+
+
diff --git a/src/ui/test_vision/test_vision.py b/src/ui/test_vision/test_vision.py
index 6a9f018..c79ea2e 100644
--- a/src/ui/test_vision/test_vision.py
+++ b/src/ui/test_vision/test_vision.py
@@ -1,158 +1,68 @@
import sys
-from lib.helpers import timing
-from PyQt5.QtCore import Qt, QTimer, pyqtSignal
-from PyQt5.QtGui import QColor, QImage, QPalette, QPixmap
-from ui import Dialog
-from ui.test_admin_permission import Test_Admin_Permission
-from ui.widget import Widget
+from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtGui import QImage, QPixmap
+from ui.test_test import Test_Test
-class Test_Vision(Widget):
- ok = pyqtSignal(dict)
+class Test_Vision(Test_Test):
request_frame = pyqtSignal()
- def __init__(self, components, recipe):
- super().__init__()
- self.components = components
- self.recipe = recipe
- # setup vision variables
- self.vision = {}
- self.vision_ok_counter = 0
+ def __init__(self, components=None, recipe=None):
if "--sim-camera" not in sys.argv:
- self.vision_ok_counter_limit = 2
+ self.ok_counter_limit = 2
else:
- self.vision_ok_counter_limit = 1
- # setup vision controls
- self.ok_timer = QTimer()
- self.ok_timer.setSingleShot(True)
- self.ok_timer.setInterval(2000)
- self.ok_timer.timeout.connect(self.emit_ok)
- # setup save frame button
- self.last_vision = None
- self.save_frame_b.setEnabled(False)
- self.save_frame_b.clicked.connect(self.save_last_vision)
- # setup vision override
- self.admin_challenged = False
- self.vision_overridden = False
- self.override_b.clicked.connect(self.override_vision)
- self.override_b.setEnabled(True)
- # setup vision staus gui
- self.status_imgs_full = {
- True: QPixmap("src/ui/imgs/success.png"),
- "": QPixmap("src/ui/imgs/neo.ico"),
- "warning": QPixmap("src/ui/imgs/warning.png"),
- False: QPixmap("src/ui/imgs/fail.png"),
- None: QPixmap("src/ui/imgs/wait.png"),
- }
- self.status_imgs_small = {k: i.scaled(32, 32, Qt.KeepAspectRatio, Qt.SmoothTransformation) for k, i in self.status_imgs_full.items()}
- self.status_palettes = {
- True: QPalette(),
- "": QPalette(),
- "warning": QPalette(),
- False: QPalette(),
- None: QPalette(),
- }
- self.status_palettes[True].setColor(QPalette.Base, Qt.green)
- self.status_palettes[False].setColor(QPalette.Base, Qt.red)
- self.status_palettes["warning"].setColor(QPalette.Base, QColor(255, 165, 0))
- self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0))
- self.visualize_vision()
+ self.ok_counter_limit = 1
+ super().__init__(components, recipe)
- def start(self):
- self.visualize_vision()
- # TESTING
- if "--test" in sys.argv:
- self.override_b.click()
- # /TESTING
+ def start(self, recipe=None):
+ super().start(recipe=recipe)
# setup camera-vision loop
self.components["galaxy_camera"].set_period(period=None) # only get frame on request
self.components["galaxy_camera"].add_sources({"test_vision": self.request_frame})
self.request_frame_connection = self.components["vision"].out.connect(self.request_frame) # request new frame as soon as vision finishes
- self.process_vision_connection = self.components["vision"].out.connect(self.process_vision)
+ self.get_connection = self.components["vision"].out.connect(self.get)
self.components["vision"].resume()
self.components["galaxy_camera"].resume()
- # start test
- self.start_time = timing()
self.request_frame.emit() # request first frame
def stop(self):
# disable camera-vision loop
self.components["galaxy_camera"].pause()
self.components["vision"].pause()
- self.disconnect(self.process_vision_connection)
+ self.disconnect(self.get_connection)
self.disconnect(self.request_frame_connection)
self.components["galaxy_camera"].remove_sources(["test_vision", ])
+ super().stop()
- def process_vision(self, data=None, override=False):
+ def get(self, data=None, override=False):
if self.ok_timer.isActive():
# avoid proccessing if vision was completed
return
- if data is None:
- data = [{"vision": {}}]
+ if data is None or data[-1] is None:
+ super().get(None, override=override)
+ return
data = data[-1]
- time = data.get("time", None)
- data = data["vision"]
- frame = data.get("frame", None)
- detections = data.get("detections", None)
- results = data.get("results", None)
- render = data.get("render", None)
- if not override:
- result_ok = data.get("vision", {}).get("ok", False)
- else:
- result_ok = True
- self.last_vision = {
- "time": time,
- "frame": frame,
- "detections": detections,
- "results": results,
- "render": render,
- "overridden": override,
- "vision_duration": timing() - self.start_time,
- "ok": result_ok,
- }
- if not override:
- if result_ok is True:
- self.vision_ok_counter += 1
- else:
- self.vision_ok_counter = 0
- else:
- self.vision_ok_counter = self.vision_ok_counter_limit
- # check if completed
- if self.vision_ok_counter >= self.vision_ok_counter_limit:
- self.stop()
- self.ok_timer.start()
- self.visualize_vision(
- time=time,
- frame=frame,
- detections=detections,
- results=results,
- render=render,
- overridden=override,
- )
+ super().get([{
+ "time": data.get("time", None),
+ "frame": data["vision"].get("frame", None),
+ "detections": data["vision"].get("detections", None),
+ "results": data["vision"].get("results", None),
+ "render": data["vision"].get("render", None),
+ }], override=override)
- def visualize_vision(self, time=None, frame=None, detections=None, results=None, render=None, overridden=False):
- self.save_frame_b.setEnabled(self.last_vision is not None)
+ def visualize(self, data=None):
+ if data is None:
+ data = {}
+ overridden = data.get("overridden", False)
+ frame = data.get("frame", None)
+ render = data.get("render", None)
if overridden:
- self.state_l.setPixmap(self.status_imgs_small["warning"])
- elif results is None:
- self.state_l.setPixmap(self.status_imgs_small[None])
- elif results.get("ok", False) is True:
- self.state_l.setPixmap(self.status_imgs_small[True])
- else:
- self.state_l.setPixmap(self.status_imgs_small[False])
- self.ok_counter_pb.setMaximum(self.vision_ok_counter_limit)
- self.ok_counter_pb.setValue(min(self.vision_ok_counter, self.vision_ok_counter_limit))
- if self.vision_ok_counter >= self.vision_ok_counter_limit:
- self.ok_counter_pb.setPalette(self.status_palettes[True])
- else:
- self.ok_counter_pb.setPalette(self.status_palettes[False])
- if overridden:
- self.img = self.status_imgs_full["warning"]
+ img = self.status_imgs_full["warning"]
elif render is not None:
- self.img = render
+ img = render
elif frame is not None:
- self.img = QPixmap.fromImage(QImage(
+ img = QPixmap.fromImage(QImage(
frame.data,
frame.shape[1], # width
frame.shape[0], # height
@@ -160,34 +70,14 @@ class Test_Vision(Widget):
QImage.Format_RGB888
))
else:
- self.img = self.status_imgs_full[None]
- self.resizeEvent()
+ img = self.status_imgs_full[None]
+ super().visualize(data, img=img)
- def save_last_vision(self):
- if self.last_vision is None:
+ def save_last(self):
+ if self.last is None:
return
- def resizeEvent(self, event=None):
- self.frame_l.setPixmap(self.img.scaled(self.frame_l.width(), self.frame_l.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
-
- def challenge_admin(self, info):
- if not self.admin_challenged:
- d = Dialog()
- d.setCentralWidget(Test_Admin_Permission(info))
- d.setModal(True)
- d.show()
- r = d.exec()
- if r == d.Accepted:
- self.admin_challenged = True
- elif r == d.Rejected:
- self.admin_challenged ^= False
- else:
- raise AssertionError("Bad admin challenge dialog return code")
- return self.admin_challenged
-
- def override_vision(self):
- if self.challenge_admin("Si sta tentando di bypassare il test di visione"):
- self.process_vision(override=True)
-
def emit_ok(self):
- self.ok.emit(self.last_vision)
+ self.last.pop("frame", None)
+ self.last.pop("render", None)
+ self.ok.emit(self.last)
diff --git a/src/ui/test_vision/test_vision.ui b/src/ui/test_vision/test_vision.ui
index 711b3ef..98b5e97 100644
--- a/src/ui/test_vision/test_vision.ui
+++ b/src/ui/test_vision/test_vision.ui
@@ -72,7 +72,7 @@
-
-
+
0
@@ -91,7 +91,7 @@
-
-
+
0
diff --git a/src/ui/widget/widget.py b/src/ui/widget/widget.py
index 25104f2..dc85718 100644
--- a/src/ui/widget/widget.py
+++ b/src/ui/widget/widget.py
@@ -8,8 +8,8 @@ from ui.dialog import Dialog
class Widget(QWidget):
- def __init__(self):
- super().__init__()
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.setAttribute(Qt.WA_DeleteOnClose)
me = self.__class__.__name__
u = get_resource("ui/{0}/{0}.ui".format(me.lower()))
diff --git a/src/ui/window/window.py b/src/ui/window/window.py
index 6999475..8e9ff6f 100644
--- a/src/ui/window/window.py
+++ b/src/ui/window/window.py
@@ -11,8 +11,8 @@ from ui.dialog import Dialog
class Window(QMainWindow):
_closing = pyqtSignal()
- def __init__(self):
- super().__init__()
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
self.setAttribute(Qt.WA_DeleteOnClose)
self.setWindowFlags(Qt.Window)
me = self.__class__.__name__