From 1a63355a8596e2c122675ed857e87dc7e3fa05e0 Mon Sep 17 00:00:00 2001 From: matteo porta Date: Wed, 24 Aug 2022 12:59:16 +0200 Subject: [PATCH] wip --- src/ui/__init__.py | 1 + src/ui/connector_step_editor/__init__.py | 1 + .../connector_step_editor.py | 9 ++ .../connector_step_editor.ui | 59 +++++++++ .../recipe_spec_and_step_editor.py | 11 +- .../recipe_spec_and_step_editor.ui | 43 +++++++ src/ui/test/test.py | 22 ++-- src/ui/test_assembly/test_assembly.py | 2 +- src/ui/test_barcodes/test_barcodes.py | 11 +- src/ui/test_connector/__init__.py | 1 + src/ui/test_connector/test_connector.py | 69 +++++++++++ src/ui/test_connector/test_connector.ui | 115 ++++++++++++++++++ src/ui/test_leak/test_leak.py | 9 +- src/ui/test_resistance/test_resistance.py | 24 ++-- src/ui/test_test/test_test.py | 18 ++- src/ui/test_vision/test_vision.py | 9 +- 16 files changed, 369 insertions(+), 35 deletions(-) create mode 100644 src/ui/connector_step_editor/__init__.py create mode 100644 src/ui/connector_step_editor/connector_step_editor.py create mode 100644 src/ui/connector_step_editor/connector_step_editor.ui create mode 100644 src/ui/test_connector/__init__.py create mode 100644 src/ui/test_connector/test_connector.py create mode 100644 src/ui/test_connector/test_connector.ui diff --git a/src/ui/__init__.py b/src/ui/__init__.py index b6d7ef0..80ad432 100644 --- a/src/ui/__init__.py +++ b/src/ui/__init__.py @@ -27,6 +27,7 @@ from .test_admin_permission import Test_Admin_Permission from .test_assembly import Test_Assembly from .test_autotest import Test_Autotest from .test_barcodes import Test_Barcodes +from .test_connector import Test_Connector from .test_home import Test_Home from .test_leak import Test_Leak from .test_resistance import Test_Resistance diff --git a/src/ui/connector_step_editor/__init__.py b/src/ui/connector_step_editor/__init__.py new file mode 100644 index 0000000..63d5caa --- /dev/null +++ b/src/ui/connector_step_editor/__init__.py @@ -0,0 +1 @@ +from .connector_step_editor import Connector_Step_Editor diff --git a/src/ui/connector_step_editor/connector_step_editor.py b/src/ui/connector_step_editor/connector_step_editor.py new file mode 100644 index 0000000..227dcab --- /dev/null +++ b/src/ui/connector_step_editor/connector_step_editor.py @@ -0,0 +1,9 @@ +from ui.editor import Editor + + +class Connector_Step_Editor(Editor): + def __init__(self, cell_widget=None): + super().__init__(cell_widget=cell_widget) + self.spec.update({ + "connector": self.connector_le, + }) diff --git a/src/ui/connector_step_editor/connector_step_editor.ui b/src/ui/connector_step_editor/connector_step_editor.ui new file mode 100644 index 0000000..f9b6b50 --- /dev/null +++ b/src/ui/connector_step_editor/connector_step_editor.ui @@ -0,0 +1,59 @@ + + + Connector_Step_Editor + + + + 0 + 0 + 204 + 67 + + + + Connector Step Editor + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 10 + 50 + false + + + + Connettore + + + + + + Connettore + + + + + + + + + + + + + + diff --git a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py index b2cca9f..ab44420 100644 --- a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py +++ b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py @@ -1,4 +1,5 @@ from lib.db import Steps +from ui.connector_step_editor import Connector_Step_Editor from ui.editor import Editor from ui.helpers import replace_widget from ui.leak_step_editor import Leak_Step_Editor @@ -10,11 +11,17 @@ class Recipe_Spec_And_Step_Editor(Editor): def __init__(self, cell_widget=None): super().__init__(cell_widget=cell_widget) self.map = { + "connector": { + "type": "connector", + "enable": self.connector_enabled_cb, + "widget": "connector_editor_w", + "editor": Connector_Step_Editor(), + }, "barcodes": { "type": "barcodes", "enable": self.barcode_enabled_cb, "widget": "barcode_editor_w", - # "editor": _Editor, + # "editor": _Step_Editor, }, "leak_1": { "type": "leak", @@ -44,7 +51,7 @@ class Recipe_Spec_And_Step_Editor(Editor): "type": "print", "enable": self.print_enabled_cb, "widget": "print_editor_w", - # "editor": _Editor, + # "editor": _Step_Editor, }, } self.spec.update({step_name: map["enable"] for step_name, map in self.map.items()}) diff --git a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui index 6816af1..4043eaf 100644 --- a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui +++ b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui @@ -40,6 +40,49 @@ Fasi di Test 0 + + + Connettore + + + + + + Qt::Horizontal + + + + 66 + 20 + + + + + + + + Fase Abilitata + + + + + + + Qt::Horizontal + + + + 65 + 20 + + + + + + + + + Scansione Codici diff --git a/src/ui/test/test.py b/src/ui/test/test.py index 796fb48..5ee2b1b 100755 --- a/src/ui/test/test.py +++ b/src/ui/test/test.py @@ -13,6 +13,7 @@ from ui.recipe_selection import Recipe_Selection from ui.test_assembly import Test_Assembly from ui.test_autotest import Test_Autotest from ui.test_barcodes import Test_Barcodes +from ui.test_connector import Test_Connector from ui.test_leak import Test_Leak from ui.test_resistance import Test_Resistance from ui.test_vision import Test_Vision @@ -43,6 +44,7 @@ class Test(Widget): # "assembly_1": Test_Assembly(img_path=self.select_step_img("assembly_1"), text=u"INSERIRE SENSORE", widget=None), "autotest": Test_Assembly(img_path=None, text=u"ESEGUIRE PROCEDURA DI AUTOTEST", widget=Test_Autotest()), "barcodes": Test_Assembly(img_path=self.select_step_img("scan"), text=u"LEGGERE IL BARCODE DEL PEZZO DA COLLAUDARE", widget=Test_Barcodes()), + "connector": Test_Assembly(img_path=self.select_step_img("scan"), text=u"COLLEGARE IL CONNETTORE INDICATO AL PEZZO E LEGGERE IL SUO BARCODE", widget=Test_Connector(run_once=True)), "done": Test_Assembly(img_path=self.select_step_img("success"), text=u"COLLAUDO COMPLETATO", widget=None), "emergency": Test_Assembly(img_path=self.select_step_img("reset_emergency"), text=u"EMERGENZA INTERVENUTA - RIPRISTINARE PULSANTE E SELEZIONARE \"RESET EMERGENZA\" DAL MEN\u00d9 \"STRUMENTI\"", widget=None), "fail": Test_Assembly(img_path=self.select_step_img("fail"), text=u"CICLO INTERROTTO", widget=None), @@ -76,10 +78,8 @@ class Test(Widget): # custom ok handlers should call next again if isinstance(w.widget, (Recipe_Selection)): w.ok.connect(self.set_recipe) - elif isinstance(w.widget, (Test_Barcodes, Test_Leak, Test_Resistance, Test_Vision)): - w.ok.connect(lambda data=None, step_name=step_name, self=weakref.ref(self): self().set_step(step_name, data)) else: - w.ok.connect(self.next) + w.ok.connect(lambda data=None, step_name=step_name, self=weakref.ref(self): self().set_step(step_name, data)) if hasattr(w, "ko"): w.ko.connect(self.fail_cycle) # TESTING @@ -204,10 +204,10 @@ class Test(Widget): self.data = {"ok": True, "overridden": False} self.archived = None w = self.cycle_available_steps[self.step.type] - if hasattr(w, "start"): - w.start(recipe=self.recipe, step=self.cycle_steps[self.cycle_index]) if w is not current_w: self.setCentralWidget(w) + if hasattr(w, "start"): + w.start(recipe=self.recipe, step=self.cycle_steps[self.cycle_index]) if self.step.type == "done": self.archived = self.done() self.next_timer.start(2000) @@ -237,6 +237,9 @@ class Test(Widget): steps.append(Steps(type="done")) steps.append(Steps(type="wait")) self.cycle_steps = steps + for w in self.cycle_available_steps.values(): + if hasattr(w, "reset"): + w.reset() # UPDATE RECIPE DISPLAY if self.recipe is not None: self.recipe_l.setText(self.recipe.name) @@ -249,10 +252,11 @@ class Test(Widget): def set_step(self, step_name, data=None): if step_name not in self.data: self.data[step_name] = {} - data["step"] = model_to_dict(self.step) - self.data[step_name][len(self.data[step_name])] = data - self.data["overridden"] = self.data["overridden"] or data.get("overridden", False) - self.data["ok"] = self.data["ok"] and data.get("ok", False) + if data is not None: + data["step"] = model_to_dict(self.step) + self.data[step_name][len(self.data[step_name])] = data + self.data["overridden"] = self.data["overridden"] or data.get("overridden", False) + self.data["ok"] = self.data["ok"] and data.get("ok", False) self.next() def done(self, ok=True): diff --git a/src/ui/test_assembly/test_assembly.py b/src/ui/test_assembly/test_assembly.py index b4b131b..cb0a0ee 100755 --- a/src/ui/test_assembly/test_assembly.py +++ b/src/ui/test_assembly/test_assembly.py @@ -35,7 +35,7 @@ class Test_Assembly(Widget): if widget is not None: replace_widget(self, "widget", widget) # widget attributes passtrough passtrough - for attr in ["ok", "ko", "start", "stop"]: + for attr in ["ok", "ko", "start", "stop", "reset"]: if hasattr(self.widget, attr): setattr(self, attr, getattr(self.widget, attr)) else: diff --git a/src/ui/test_barcodes/test_barcodes.py b/src/ui/test_barcodes/test_barcodes.py index 50d6c5a..ca877f9 100644 --- a/src/ui/test_barcodes/test_barcodes.py +++ b/src/ui/test_barcodes/test_barcodes.py @@ -5,8 +5,8 @@ from ui.test_test import Test_Test class Test_Barcodes(Test_Test): - def __init__(self, components=None, recipe=None, step=None): - super().__init__(components=components, recipe=recipe, step=step) + def __init__(self, components=None, recipe=None, step=None, run_once=False): + super().__init__(components=components, recipe=recipe, step=step, run_once=run_once) self.barcodes_spec = { "serial": self.check_serial_barcode } @@ -16,7 +16,8 @@ class Test_Barcodes(Test_Test): def start(self, recipe=None, step=None): super().start(recipe=recipe, step=step) - self.barcodes = {} + if self.run_once is True and self.done is True and self.done_ok is True: + return self.visualize() self.barcodes_le.setPalette(self.status_palettes[None]) self.barcodes_le.setText("") @@ -25,6 +26,10 @@ class Test_Barcodes(Test_Test): # def stop(self): # super().stop() + def reset(self): + super().reset() + self.barcodes = {} + def get(self, data=None, override=False): if self.done: # avoid proccessing if completed return diff --git a/src/ui/test_connector/__init__.py b/src/ui/test_connector/__init__.py new file mode 100644 index 0000000..522247a --- /dev/null +++ b/src/ui/test_connector/__init__.py @@ -0,0 +1 @@ +from .test_connector import Test_Connector diff --git a/src/ui/test_connector/test_connector.py b/src/ui/test_connector/test_connector.py new file mode 100644 index 0000000..2b255ff --- /dev/null +++ b/src/ui/test_connector/test_connector.py @@ -0,0 +1,69 @@ +from lib.helpers import timing +from PyQt5.QtGui import QKeySequence +from PyQt5.QtWidgets import QShortcut +from ui.test_test import Test_Test + + +class Test_Connector(Test_Test): + def __init__(self, components=None, recipe=None, step=None, run_once=False): + super().__init__(components=components, recipe=recipe, step=step, run_once=run_once) + QShortcut(QKeySequence("Return"), self).activated.connect(self.get) + QShortcut(QKeySequence("Enter"), self).activated.connect(self.get) + self.connector_le.setFocus() + + def start(self, recipe=None, step=None): + super().start(recipe=recipe, step=step) + if self.run_once is True and self.done is True and self.done_ok is True: + return + self.visualize() + self.expected_l.setText(str(self.step.spec.get("connector", "-"))) + self.connector_le.setPalette(self.status_palettes[None]) + self.connector_le.setText("") + self.connector_le.setFocus() + + # def stop(self): + # super().stop() + + # def reset(self): + # super().reset() + + def get(self, data=None, override=False): + if self.done: # avoid proccessing if completed + return + if data is None: + data = self.connector_le.text() + if not len(data): + data = None + if data is None: + super().get(None, override=override) + return + connector_ok = data == self.step.spec.get("connector", None) + if connector_ok: + self.connector_le.setPalette(self.status_palettes[True]) + else: + self.connector_le.setPalette(self.status_palettes[False]) + self.connector_le.setText("") + self.connector_le.setFocus() + if connector_ok is True: + result = data + ok = True + else: + result = None + ok = None + super().get([{ + "time": timing(), + "results": { + "ok": ok, + "result": result, + "data": data, + }, + }], override=override, fail=ok is False) + + def visualize(self, data=None): + if data is None: + data = {} + self.connector_l.setText(str(data.get("results", {}).get("data", "-"))) + super().visualize(data) + + def check_serial_barcode(self, barcode=None): + return barcode is not None and len(barcode) diff --git a/src/ui/test_connector/test_connector.ui b/src/ui/test_connector/test_connector.ui new file mode 100644 index 0000000..08db63f --- /dev/null +++ b/src/ui/test_connector/test_connector.ui @@ -0,0 +1,115 @@ + + + Test_Connector + + + + 0 + 0 + 235 + 156 + + + + Test Connector + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + FORZA ACCETTAZIONE + + + + + + + + 0 + 0 + + + + Stato + + + + + + - + + + + + + + Connettore utilizzato + + + + + + + Connettore da utilizzare + + + + + + + - + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + - + + + + + + + + + + connector_le + override_b + + + + diff --git a/src/ui/test_leak/test_leak.py b/src/ui/test_leak/test_leak.py index 67c8961..cc418e7 100644 --- a/src/ui/test_leak/test_leak.py +++ b/src/ui/test_leak/test_leak.py @@ -4,13 +4,15 @@ from ui.test_test import Test_Test class Test_Leak(Test_Test): - def __init__(self, components=None, recipe=None, step=None): - super().__init__(components=components, recipe=recipe, step=step) + def __init__(self, components=None, recipe=None, step=None, run_once=False): + super().__init__(components=components, recipe=recipe, step=step, run_once=run_once) self.start_b.clicked.connect(lambda checked, self=weakref.ref(self): self().components["tecna_t3"].start_test()) self.stop_b.clicked.connect(lambda checked, self=weakref.ref(self): self().components["tecna_t3"].stop_test()) def start(self, recipe=None, step=None): super().start(recipe=recipe, step=step) + if self.run_once is True and self.done is True and self.done_ok is True: + return # setup test loop self.components["tecna_t3"].write_recipe(self.recipe, self.step) self.get_connection = self.components["tecna_t3"].out.connect(self.get) @@ -31,6 +33,9 @@ class Test_Leak(Test_Test): self.start_b.setEnabled(False) self.stop_b.setEnabled(False) + # def reset(self): + # super().reset() + def get(self, data=None, override=False): if self.done: # avoid proccessing if completed return diff --git a/src/ui/test_resistance/test_resistance.py b/src/ui/test_resistance/test_resistance.py index 9976375..ecab0d5 100644 --- a/src/ui/test_resistance/test_resistance.py +++ b/src/ui/test_resistance/test_resistance.py @@ -2,30 +2,26 @@ from ui.test_test import Test_Test class Test_Resistance(Test_Test): - def __init__(self, components=None, recipe=None, step=None): - super().__init__(components=components, recipe=recipe, step=step) - def start(self, recipe=None, step=None): super().start(recipe=recipe, step=step) + if self.run_once is True and self.done is True and self.done_ok is True: + return # setup test loop self.components["multicomp"].set_resistance_scale(self.step.spec.get("expected", 0)) self.get_connection = self.components["multicomp"].out.connect(self.get) self.components["multicomp"].resume() - if self.step is not None: - self.expected_l.setText(str(self.step.spec.get("expected", "-"))) - self.tolerance_l.setText(str(self.step.spec.get("tolerance", "-"))) - else: - self.expected_l.setText("-") - self.tolerance_l.setText("-") + self.expected_l.setText(str(self.step.spec.get("expected", "-"))) + self.tolerance_l.setText(str(self.step.spec.get("tolerance", "-"))) def stop(self): # disable test loop self.components["multicomp"].pause() self.disconnect(self.get_connection) - self.expected_l.setText("-") - self.tolerance_l.setText("-") super().stop() + # def reset(self): + # super().reset() + def get(self, data=None, override=False): if self.done: # avoid proccessing if completed return @@ -40,9 +36,11 @@ class Test_Resistance(Test_Test): isinstance(result, (int, float)), isinstance(expected, (int, float)), isinstance(tolerance, (int, float)), - abs(result - expected) <= tolerance ]): - ok = True + if abs(result - expected) <= tolerance: + ok = True + else: + ok = None else: ok = None super().get([{ diff --git a/src/ui/test_test/test_test.py b/src/ui/test_test/test_test.py index 77a61c0..3e53cf0 100644 --- a/src/ui/test_test/test_test.py +++ b/src/ui/test_test/test_test.py @@ -13,16 +13,18 @@ class Test_Test(Widget): ok = pyqtSignal(dict) ko = pyqtSignal(dict) - def __init__(self, components=None, recipe=None, step=None): + def __init__(self, components=None, recipe=None, step=None, run_once=False): super().__init__() self.components = components self.recipe = recipe self.step = step + self.run_once = run_once # setup variables self.ok_counter = 0 self.ok_counter_limit = 1 # setup controls self.done = False + self.done_ok = None self.ok_timer = QTimer() self.ok_timer.setSingleShot(True) self.ok_timer.setInterval(2000) @@ -75,8 +77,10 @@ class Test_Test(Widget): self.admin_challenged = False self.recipe = recipe self.step = step - self.ok_counter = 0 - self.done = False + if self.run_once is True and self.done is True and self.done_ok is True: + self.emit_ok() + return + self.reset() self.override_b.setEnabled(True) self.visualize() # start test @@ -90,6 +94,12 @@ class Test_Test(Widget): def stop(self): pass + def reset(self): + self.ok_counter = 0 + self.done = False + self.done_ok = None + self.last = None + def get(self, data=None, override=False, fail=False): if self.done: # avoid proccessing if completed return @@ -126,11 +136,13 @@ class Test_Test(Widget): # check if completed if fail: self.done = True + self.done_ok = False self.override_b.setEnabled(False) self.stop() self.ko_timer.start() elif self.ok_counter >= self.ok_counter_limit: self.done = True + self.done_ok = True self.override_b.setEnabled(False) self.stop() self.ok_timer.start() diff --git a/src/ui/test_vision/test_vision.py b/src/ui/test_vision/test_vision.py index 986effe..0384b8a 100644 --- a/src/ui/test_vision/test_vision.py +++ b/src/ui/test_vision/test_vision.py @@ -10,7 +10,7 @@ from ui.test_test import Test_Test class Test_Vision(Test_Test): request_frame = pyqtSignal() - def __init__(self, components=None, recipe=None, step=None): + def __init__(self, components=None, recipe=None, step=None, run_once=False): if "--sim-camera" not in sys.argv: self.ok_counter_limit = 2 else: @@ -21,7 +21,7 @@ class Test_Vision(Test_Test): "expected": "ATTESO", "score": "PUNTEGGIO", } - super().__init__(components=components, recipe=recipe, step=step) + super().__init__(components=components, recipe=recipe, step=step, run_once=run_once) self.results_tw.setColumnCount(len(self.results_table_headers)) self.results_tw.setHorizontalHeaderLabels(self.results_table_headers.values()) self.results_tw.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) @@ -29,6 +29,8 @@ class Test_Vision(Test_Test): def start(self, recipe=None, step=None): super().start(recipe=recipe, step=step) + if self.run_once is True and self.done is True and self.done_ok is True: + return # 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}) @@ -53,6 +55,9 @@ class Test_Vision(Test_Test): self.components["galaxy_camera"].remove_sources(["test_vision", ]) super().stop() + # def reset(self): + # super().reset() + def get(self, data=None, override=False): if self.done: # avoid proccessing if completed return