diff --git a/config/machine_settings/st-ten-8.ini b/config/machine_settings/st-ten-8.ini index b365520..a0730d4 100644 --- a/config/machine_settings/st-ten-8.ini +++ b/config/machine_settings/st-ten-8.ini @@ -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 diff --git a/src/components/tecna_marposs_provaset_t3.py b/src/components/tecna_marposs_provaset_t3.py index b4143a7..d2bba1b 100644 --- a/src/components/tecna_marposs_provaset_t3.py +++ b/src/components/tecna_marposs_provaset_t3.py @@ -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): diff --git a/src/components/tecna_marposs_provaset_t3l_registers.py b/src/components/tecna_marposs_provaset_t3l_registers.py index 93ac2e1..6e7a78c 100644 --- a/src/components/tecna_marposs_provaset_t3l_registers.py +++ b/src/components/tecna_marposs_provaset_t3l_registers.py @@ -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 % diff --git a/src/main.py b/src/main.py index 55cc62d..4e73e78 100644 --- a/src/main.py +++ b/src/main.py @@ -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) diff --git a/src/ui/barcode_recipe_selection/barcode_recipe_selection.py b/src/ui/barcode_recipe_selection/barcode_recipe_selection.py index 07f2b7b..d8dcd01 100644 --- a/src/ui/barcode_recipe_selection/barcode_recipe_selection.py +++ b/src/ui/barcode_recipe_selection/barcode_recipe_selection.py @@ -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): diff --git a/src/ui/login/login.py b/src/ui/login/login.py index bbc0d52..dcb0f4d 100755 --- a/src/ui/login/login.py +++ b/src/ui/login/login.py @@ -60,4 +60,4 @@ class Login(Widget): def show_osk(self): self.password_le.setFocus() if platform.system().lower() == 'windows': - subprocess.Popen(["open_osk.bat"]) # OPEN ON SCREEN KEYBOARD + subprocess.Popen(["open_osk.bat"]) # OPEN ON SCREEN KEYBOARD diff --git a/src/ui/recipe_selection/recipe_selection.py b/src/ui/recipe_selection/recipe_selection.py index 352b656..63f7b87 100755 --- a/src/ui/recipe_selection/recipe_selection.py +++ b/src/ui/recipe_selection/recipe_selection.py @@ -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) @@ -156,7 +158,7 @@ class Recipe_Selection(Widget): def check_selected(self, selected=None): if selected is not None and len(selected) == 1: - selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line) + selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line) if selected >= 0 and selected < len(self.crud.data_index): selected = self.crud.data_index[selected] if selected is not None: @@ -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, diff --git a/src/ui/test/test.py b/src/ui/test/test.py index cde39a5..2f9b3c1 100755 --- a/src/ui/test/test.py +++ b/src/ui/test/test.py @@ -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 self.step.type == "barcode_recipe_selection": - if data is not None: - self.cycle_available_steps["barcode_recipe_selection"].widget.get(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: - # fixture removed - self.fail_cycle() - self.change_recipe() + pass + else: - if data is not None: - self.set_recipe_mode_barcode() + # fixture removed + self.tag_loaded_recipe = None + self.fail_cycle() + self.change_recipe()