This commit is contained in:
matteo porta 2022-08-24 12:59:16 +02:00
parent fa9921c9bc
commit 1a63355a85
16 changed files with 369 additions and 35 deletions

View File

@ -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

View File

@ -0,0 +1 @@
from .connector_step_editor import Connector_Step_Editor

View File

@ -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,
})

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Connector_Step_Editor</class>
<widget class="QWidget" name="Connector_Step_Editor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>204</width>
<height>67</height>
</rect>
</property>
<property name="windowTitle">
<string>Connector Step Editor</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="title">
<string>Connettore</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Connettore</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="connector_le"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -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()})

View File

@ -40,6 +40,49 @@ Fasi di Test</string>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_7">
<attribute name="title">
<string>Connettore</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>66</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="connector_enabled_cb">
<property name="text">
<string>Fase Abilitata</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_14">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>65</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="3">
<widget class="QWidget" name="connector_editor_w" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Scansione Codici</string>

View File

@ -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,6 +252,7 @@ class Test(Widget):
def set_step(self, step_name, data=None):
if step_name not in self.data:
self.data[step_name] = {}
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)

View File

@ -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:

View File

@ -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

View File

@ -0,0 +1 @@
from .test_connector import Test_Connector

View File

@ -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)

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Test_Connector</class>
<widget class="QWidget" name="Test_Connector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>235</width>
<height>156</height>
</rect>
</property>
<property name="windowTitle">
<string>Test Connector</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="13" column="0">
<widget class="QLineEdit" name="connector_le"/>
</item>
<item row="14" column="0">
<widget class="QPushButton" name="override_b">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>FORZA ACCETTAZIONE</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Stato</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1">
<widget class="QLabel" name="connector_l">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Connettore utilizzato</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Connettore da utilizzare</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="expected_l">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QLabel" name="state_l">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>connector_le</tabstop>
<tabstop>override_b</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -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

View File

@ -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("-")
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,11 +36,13 @@ class Test_Resistance(Test_Test):
isinstance(result, (int, float)),
isinstance(expected, (int, float)),
isinstance(tolerance, (int, float)),
abs(result - expected) <= tolerance
]):
if abs(result - expected) <= tolerance:
ok = True
else:
ok = None
else:
ok = None
super().get([{
"time": data.get("time", None),
"results": {

View File

@ -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()

View File

@ -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