Merge remote-tracking branch 'origin/master'

This commit is contained in:
Eduardo 2024-02-29 17:16:05 +01:00
commit 51fe8bc283
8 changed files with 75 additions and 53 deletions

View File

@ -13,36 +13,36 @@ vision_saver: absent
vision: absent
screwdriver: absent
digital_io: present
#digital_io_flush_blow: present
barcode_recipe_selection: present
fixture_id: present
discard_box: present
enforce_piece_removal: yes
external_flush_blow: present # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH
#external_flush_blow: present # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH
[tecna_t3]
port: COM4
model: t3l
model: t3p
[label_printer]
platform: windows
printer: zd421
[digital_io]
# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
id_flush_blow: USB-5860,BID#0
blow_on: 3 # INPUT VALVE TO SERVICE AIR
out_channel_select: 2 # AIR OUT VALVE (0=CH1, 1=CH2)
in_channel_select: 0 # AIR IN VALVE (0=CH1, 1=CH2)
flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
blow_led:7 # CLEAN INDICATOR
ch1_led:6 # CHANNEL 1 ACTIVE INDICATOR
ch2_led:5 # CHANNEL 2 ACTIVE INDICATOR
flush_led:4 # FLUSH INDICATOR
# OUTPUT MAP FOR FIXTURE CONNECTOR
id_fixture: USB-5862,BID#0
discard_idx:12 # BIT NUMBER OF THE I/0 MODULE USED FOR DISCARD SENSING
[digital_io_flush_blow]
id: USB-5860,BID#0
# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
blow_on: 0 # INPUT VALVE TO SERVICE AIR
flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
blow_led:4 # CLEAN INDICATOR
ch1_led:3 # CHANNEL 1 ACTIVE INDICATOR
flush_led:2 # FLUSH INDICATOR
[fixture_rfid]
port: COM5
@ -83,7 +83,7 @@ tempo_svuotamento_2: 1
pressione_svuotamento_2: 100
canale_di_prova_2: 2
modello_etichetta: EtichettaR5_Montaggio_1prova.prn
pid_pressure_correction: 110
pid_pressure_correction: 105
[autotest_leak]
enabled: true

View File

@ -316,6 +316,7 @@ class TecnaMarpossProvasetT3(ModbusComponent):
self.log.debug(str(spec))
for register, value in spec.items():
self.write(register, value)
pass
@db.connection_context()
def store_recipes(self, recipes):

View File

@ -316,7 +316,7 @@ registers = {
"PB - Burst pressure": [743 - 1, {"dt": "16bit_uint", "f": 1505, }],
"BD - Burst drop / PD - Delta Aperture": [744 - 1, {"dt": "16bit_uint", "f": 1505, }],
"FSL - Discharge limit": [745 - 1, {"dt": "16bit_uint", "f": 1505, }],
"PID: pressure correction": [746 - 1, {"dt": "16bit_uint", "g": 100, }],
"PID: pressure correction": [746 - 1, {"dt": "16bit_uint", "g": 110, }],
# Offset electronic regulator Format: xx.xx%
"PR+ - Max pressure tolerance % (P+)": [747 - 1, {"dt": "16bit_uint", "g": 10, }],
# Format: x.x %

View File

@ -69,7 +69,7 @@ try:
TecnaMarpossProvasetT3, FurnessControlsLeakTester, TecnaScrewdriver, USB_586x, RFID_PN532)
from lib.db import Users
from lib.helpers import ConfigReader
from PyQt5.QtCore import QObject, QThread, pyqtSignal
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QMessageBox
from ui import About, Archive, Login, Main_Window, Test, Users_Management, Recipe_Selection, \
Barcode_Recipe_Selection
@ -88,6 +88,7 @@ try:
def __init__(self, parent=None):
# print(f"MAIN {int(QThread.currentThreadId())}", flush=True)
super().__init__()
self.tag_loaded_recipe = None
self.do.connect(self._do)
try:
# READ CONFIG
@ -138,6 +139,10 @@ try:
self.threads[component_name] = QThread()
self.threads[component_name].setTerminationEnabled(True)
self.components[component_name].moveToThread(self.threads[component_name])
if "fixture_id" in self.components.keys():
self.components["fixture_id"].new_id_signal.connect(self.load_recipe_from_rfid)
for component_name, thread in self.threads.items():
component = self.components[component_name]
thread.started.connect(component.start)
@ -263,6 +268,9 @@ try:
def reprint_label(self):
self.main_window.centralWidget().reprint_label()
@pyqtSlot(str)
def load_recipe_from_rfid(self, data):
self.tag_loaded_recipe = data
if __name__ == "__main__":
app = QApplication(sys.argv)

View File

@ -55,6 +55,8 @@ class Barcode_Recipe_Selection(Test_Test):
self.barcode_input_l.setPalette(self.status_palettes[None])
self.barcode_input_l.setPlainText("")
self.barcode_input_l.setFocus()
if self.parent.tag_loaded_recipe is not None:
self.get(self.parent.tag_loaded_recipe)
self.focus_timer.start(500)
def debounce(self):

View File

@ -30,7 +30,7 @@ class Recipe_Selection(Widget):
global noner
super().__init__()
self.config = config
self.second_leak_test_enabled=self.config["hardware_config"]["second_leak_test"] == "present"
self.second_leak_test_enabled = self.config["hardware_config"]["second_leak_test"] == "present"
self.defaults = self.config.get("recipes_defaults", noner)
self.unsupported_steps = unsupported_steps
if not self.second_leak_test_enabled:
@ -57,8 +57,8 @@ class Recipe_Selection(Widget):
}
filters = {"archived": False}
step_defaults = self.read_steps(self.config.get("recipes_defaults", noner), noner)
custom_label_folder=f"config/label_templates/{str(self.config.machine_id)}/"
standard_label_folder=f"config/label_templates/"
custom_label_folder = f"config/label_templates/{str(self.config.machine_id)}/"
standard_label_folder = f"config/label_templates/"
if os.path.exists(custom_label_folder):
label_folder = custom_label_folder
else:
@ -88,8 +88,10 @@ class Recipe_Selection(Widget):
"spec": {
"count": len(self.config.get("recipes_defaults", noner)["dimensione_lotto_abilitata"]) and "count" not in self.unsupported_steps,
"connector": len(self.config.get("recipes_defaults", noner)["verifica_connettore_abilitata"]) and "connector" not in self.unsupported_steps,
"barcodes": len(self.config.get("recipes_defaults", noner)["verifica_codice_a_barre_abilitata"]) and "barcodes" not in self.unsupported_steps,
"resistance": len(self.config.get("recipes_defaults", noner)["verifica_resistenza_connettore_abilitata"]) and "resistance" not in self.unsupported_steps,
"barcodes": len(
self.config.get("recipes_defaults", noner)["verifica_codice_a_barre_abilitata"]) and "barcodes" not in self.unsupported_steps,
"resistance": len(
self.config.get("recipes_defaults", noner)["verifica_resistenza_connettore_abilitata"]) and "resistance" not in self.unsupported_steps,
"screws": len(self.config.get("recipes_defaults", noner)["avvitatura_abilitata"]) and "screws" not in self.unsupported_steps,
"instruction": len(self.config.get("recipes_defaults", noner)["istruzione_abilitata"]) and "instruction" not in self.unsupported_steps,
"leak_1": len(self.config.get("recipes_defaults", noner)["prova_tenuta_abilitata"]) and "leak_1" not in self.unsupported_steps,
@ -127,9 +129,9 @@ class Recipe_Selection(Widget):
self.crud.db_tw.setColumnWidth(4, 200)
self.crud.db_tw.setColumnWidth(5, 400)
if session.is_admin:
self.import_b.clicked.connect(lambda checked, self=weakref.ref(self): self().import_recipes())
self.export_b.clicked.connect(lambda checked, self=weakref.ref(self): self().export_recipes())
self.delete_all_b.clicked.connect(lambda checked, self=weakref.ref(self): self().delete_recipes())
self.import_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().import_recipes())
self.export_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().export_recipes())
self.delete_all_b.clicked.connect(lambda checked, selfi=weakref.ref(self): selfi().delete_recipes())
else:
self.import_b.setVisible(False)
self.export_b.setVisible(False)
@ -174,8 +176,8 @@ class Recipe_Selection(Widget):
if self.selected is not None:
self.ok.emit(self.crud.db.table_model.get_by_id(self.selected))
def get_def(self,dict,key):
val=dict.get(key,self.defaults[key])
def get_def(self, dict, key):
val = dict.get(key, self.defaults[key])
return val if val != "" else self.defaults[key]
def read_steps(self, row, defaults=None):
@ -183,7 +185,7 @@ class Recipe_Selection(Widget):
global noner
defaults = self.config.get("recipes_defaults", noner)
barcode_serial_field = self.config.get("recipe", {}).get("barcode_serial_field", "codice_a_barre").strip()
decsep= locale.localeconv()["decimal_point"]
decsep = locale.localeconv()["decimal_point"]
rcsv = row.get("r nominale", defaults["r nominale"]).replace(" ", "").replace(",", decsep).replace("Ω", "").replace("?", "")
if rcsv == "":
rcsv = "999"
@ -192,7 +194,7 @@ class Recipe_Selection(Widget):
"count": {
"amount": row.get("dimensione_lotto", defaults["dimensione_lotto"]),
"warning_img": row.get("immagine_warning", ""),
"require_discard_piece": row.get("richiedi_inserimento_scarto",defaults["richiedi_inserimento_scarto"])
"require_discard_piece": row.get("richiedi_inserimento_scarto", defaults["richiedi_inserimento_scarto"])
},
"connector": {
"connector": row.get("connettore", defaults["connettore"]),
@ -203,8 +205,8 @@ class Recipe_Selection(Widget):
"resistance": {
"scale": locale.atof(row.get("scala_resistenza", defaults["scala_resistenza"])),
"expected": locale.atof(rcsv),
"tolerance_pos": locale.atof(self.get_def(row,"tolleranza_resistenza_pos")),
"tolerance_neg": locale.atof(self.get_def(row,"tolleranza_resistenza_neg")),
"tolerance_pos": locale.atof(self.get_def(row, "tolleranza_resistenza_pos")),
"tolerance_neg": locale.atof(self.get_def(row, "tolleranza_resistenza_neg")),
},
"screws": {
"quantity": row.get("viti", defaults["viti"])
@ -214,9 +216,11 @@ class Recipe_Selection(Widget):
"pre_filling_time": int(row.get("tempo_pre_riempimento", defaults["tempo_pre_riempimento"])),
"pre_filling_pressure": int(row.get("pressione_pre_riempimento", defaults["pressione_pre_riempimento"])),
"filling_time": int(row.get("tempo_riempimento", defaults["tempo_riempimento"])),
"settling_time": int(self.get_def(row,"tempo_assestamento")),
"settling_pressure_min_percent": int(row.get("percentuale_minima_pressione_assestamento", defaults["percentuale_minima_pressione_assestamento"])),
"settling_pressure_max_percent": int(row.get("percentuale_massima_pressione_assestamento", defaults["percentuale_massima_pressione_assestamento"])),
"settling_time": int(self.get_def(row, "tempo_assestamento")),
"settling_pressure_min_percent": int(
row.get("percentuale_minima_pressione_assestamento", defaults["percentuale_minima_pressione_assestamento"])),
"settling_pressure_max_percent": int(
row.get("percentuale_massima_pressione_assestamento", defaults["percentuale_massima_pressione_assestamento"])),
"test_time": int(row.get("tempo_di_test", defaults["tempo_di_test"])),
"test_pressure_qneg": int(row.get("pressione_di_test_delta_minimo", defaults["pressione_di_test_delta_minimo"])),
"test_pressure": int(row.get("pressione_di_test", defaults["pressione_di_test"])),
@ -232,8 +236,10 @@ class Recipe_Selection(Widget):
"pre_filling_pressure": int(row.get("pressione_pre_riempimento_2", defaults["pressione_pre_riempimento_2"])),
"filling_time": int(row.get("tempo_riempimento_2", defaults["tempo_riempimento_2"])),
"settling_time": int(row.get("tempo_assestamento_2", defaults["tempo_assestamento_2"])),
"settling_pressure_min_percent": int(row.get("percentuale_minima_pressione_assestamento_2", defaults["percentuale_minima_pressione_assestamento_2"])),
"settling_pressure_max_percent": int(row.get("percentuale_massima_pressione_assestamento_2", defaults["percentuale_massima_pressione_assestamento_2"])),
"settling_pressure_min_percent": int(
row.get("percentuale_minima_pressione_assestamento_2", defaults["percentuale_minima_pressione_assestamento_2"])),
"settling_pressure_max_percent": int(
row.get("percentuale_massima_pressione_assestamento_2", defaults["percentuale_massima_pressione_assestamento_2"])),
"test_time": int(row.get("tempo_di_test_2", defaults["tempo_di_test_2"])),
"test_pressure_qneg": int(row.get("pressione_di_test_delta_minimo_2", defaults["pressione_di_test_delta_minimo_2"])),
"test_pressure": int(row.get("pressione_di_test_2", defaults["pressione_di_test_2"])),
@ -249,7 +255,7 @@ class Recipe_Selection(Widget):
},
"print": {
"template": row.get(print_template_field, defaults["modello_etichetta"]),
"labeltxt_1": row.get("testo_etich_1",""),
"labeltxt_1": row.get("testo_etich_1", ""),
"labeltxt_2": row.get("testo_etich_2", ""),
"labeltxt_3": row.get("testo_etich_3", ""),
"labeltxt_4": row.get("testo_etich_4", ""),
@ -278,12 +284,11 @@ class Recipe_Selection(Widget):
description_field = self.config.get("recipe", {}).get("description_field", "descrizione").strip()
barcode_enable_field = self.config.get("recipe", {}).get("barcode_enable_field", "verifica_codice_a_barre_abilitata").strip()
with open(csv_path, "r",encoding="utf-8-sig") as f:
with open(csv_path, "r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
count = 0
for ucrow in reader:
row= dict((k.lower(), v) for k, v in ucrow.items())
row = dict((k.lower(), v) for k, v in ucrow.items())
recipe_name = row.get(recipe_name_field, defaults["codice_ricetta"])
steps_specs = self.read_steps(row, defaults=defaults)
try:
@ -299,7 +304,7 @@ class Recipe_Selection(Widget):
recipe_is_new = True
for step_name, step_spec in steps_specs.items():
step = steps[step_name]
#step.type = re.sub(r"^(.*)_[0-9]+$", r"\1", step_name)
# step.type = re.sub(r"^(.*)_[0-9]+$", r"\1", step_name)
step.type = step_name
step.spec = step_spec
if recipe_is_new:
@ -311,9 +316,11 @@ class Recipe_Selection(Widget):
recipe.description = row.get(description_field, defaults["descrizione"])
recipe.spec = {
"count": len(row.get("dimensione_lotto_abilitata", defaults["dimensione_lotto_abilitata"])) and "count" not in self.unsupported_steps,
"connector": len(row.get("verifica_connettore_abilitata", defaults["verifica_connettore_abilitata"])) and "connector" not in self.unsupported_steps,
"connector": len(
row.get("verifica_connettore_abilitata", defaults["verifica_connettore_abilitata"])) and "connector" not in self.unsupported_steps,
"barcodes": len(row.get(barcode_enable_field, defaults["verifica_codice_a_barre_abilitata"])) and "barcodes" not in self.unsupported_steps,
"resistance": len(row.get("verifica_resistenza_connettore_abilitata", defaults["verifica_resistenza_connettore_abilitata"])) and "resistance" not in self.unsupported_steps,
"resistance": len(row.get("verifica_resistenza_connettore_abilitata",
defaults["verifica_resistenza_connettore_abilitata"])) and "resistance" not in self.unsupported_steps,
"screws": len(row.get("avvitatura_abilitata", defaults["avvitatura_abilitata"])) and "screws" not in self.unsupported_steps,
"instruction": len(row.get("istruzione_abilitata", defaults["istruzione_abilitata"])) and "instruction" not in self.unsupported_steps,
"leak_1": len(row.get("prova_tenuta_abilitata", defaults["prova_tenuta_abilitata"])) and "leak_1" not in self.unsupported_steps,

View File

@ -155,6 +155,7 @@ class Test(Widget):
if "fixture_id" in self.components.keys():
self.components["fixture_id"].new_id_signal.connect(self.load_recipe_from_rfid)
self.tag_loaded_recipe = self.main_window.tag_loaded_recipe
# TESTING
if "--test" in sys.argv:
@ -622,7 +623,7 @@ class Test(Widget):
psetmaxp_a = leak_test_1_step_spec.get("settling_pressure_max_percent", 0) * (100 + leak_test_1_step_spec.get("test_pressure_qpos", 0) / 100)
psetminp2_a = leak_test_2_step_spec.get("settling_pressure_min_percent", 0) * (100 + leak_test_2_step_spec.get("test_pressure_qneg", 0) / 100)
psetmaxp2_a = leak_test_2_step_spec.get("settling_pressure_max_percent", 0) * (100 + leak_test_2_step_spec.get("test_pressure_qpos", 0) / 100)
leak_test_1_results["Running test: pressure at the end of measure"] = leak_test_1_results["Running test: pressure at the end of settling"] - leak_test_1_results["Running test: measured leak"]
leak_test_1_results["Running test: pressure at the end of measure"] = leak_test_1_results["Running test: pressure at the end of settling"] + leak_test_1_results["Running test: measured leak"]
printer_fields = self.print_step.spec
context = {
# RECIPE DATA
@ -717,13 +718,16 @@ class Test(Widget):
@pyqtSlot(str)
def load_recipe_from_rfid(self, data):
if data not in(None,''):
self.tag_loaded_recipe = data
if self.step.type == "barcode_recipe_selection":
if data is not None:
self.cycle_available_steps["barcode_recipe_selection"].widget.get(data)
else:
pass
else:
# fixture removed
self.tag_loaded_recipe = None
self.fail_cycle()
self.change_recipe()
else:
if data is not None:
self.set_recipe_mode_barcode()