diff --git a/simulate.sh b/simulate.sh index cad15a1..3326dc0 100755 --- a/simulate.sh +++ b/simulate.sh @@ -17,6 +17,7 @@ python -B -u "./src/main.py" \ --auto-login-admin \ --auto-select \ --debugger-workaround \ +--enable-saving-tecna-recipes \ --no-edgetpu \ --no-gpu \ --panel \ @@ -39,9 +40,17 @@ $* 2> >(sed $'s/.*/\e[31m&\e[m/' >&2) # & # --no-gui \ # --no-tflite \ # --recipes-management \ +# --save-tecna-recipes \ # --sim-archiver \ +# --sim-autotest \ # --sim-vision \ # --steps-management \ +# --test \ +# --test-barcodes \ +# --test-connector \ +# --test-leak \ +# --test-resistance \ +# --test-screws \ # --users-management \ # sudo renice -n -10 $! # fg diff --git a/src/components/tecna_marposs_provaset_t3.py b/src/components/tecna_marposs_provaset_t3.py index 11f7700..b05d876 100644 --- a/src/components/tecna_marposs_provaset_t3.py +++ b/src/components/tecna_marposs_provaset_t3.py @@ -1,3 +1,7 @@ +from lib.db import Recipes, Steps, db +from PyQt5.QtCore import QSemaphore, pyqtSignal +from PyQt5.QtWidgets import QMessageBox + from .component import Component from .modbus_component import ModbusComponent from .tecna_marposs_provaset_t3l_registers import registers as t3l_registers @@ -11,6 +15,9 @@ from .tecna_marposs_provaset_t3p_registers import registers as t3p_registers class TecnaMarpossProvasetT3(ModbusComponent): + _store_recipes_signal = pyqtSignal(object) + _store_recipes_lock = QSemaphore(0) + def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True): super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded, registers=None) @@ -22,6 +29,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): def config_changed(self): super().config_changed() + self._store_recipes_signal.connect(self._store_recipes) # self.pins = { # "admin_pin": self.config.get("admin_pin", None), # "modify_pin": self.config.get("modify_pin", None), @@ -37,6 +45,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.") self.set_measure_units() self.units = self.get_measure_units() + self.max_program_number = self.read("Max number of programs") self.log.info(f"units: {self.units}") # def unlock_tecna(self, **kwargs): @@ -249,7 +258,9 @@ class TecnaMarpossProvasetT3(ModbusComponent): self.write(register, value) super()._set(val) - def start_test(self, table=100): + def start_test(self, table=None): + if table is None: + table = self.max_program_number self.log.info(f"starting test table {table!r}") self.write("Source of test program number selection", "FROM PARAMETER (SET BY LCD OR SERIAL LINE)") self.write("Selected program", table) @@ -272,13 +283,18 @@ class TecnaMarpossProvasetT3(ModbusComponent): "Running test: result", ]} - def write_recipe(self, recipe, step, table=100): + def write_recipe(self, recipe, step, table=None): + if table is None: + table = self.max_program_number recipe_name = recipe.part_number[:16].encode("ascii") recipe_name += b"\x00" * (16 - len(recipe_name)) + recipe_barcode = f"j{recipe.part_number}"[:16].encode("ascii") + recipe_barcode += b"\x00" * (24 - len(recipe_barcode)) spec = { "Flag: Instrument settings": 0b0000000000000000, "Test program for read/write operation": table, - **{719 - 1 + i: (recipe_name[i * 2 + 1] << 8) + recipe_name[i * 2] for i in range(8)}, + **{719 - 1 + i: (recipe_name[i * 2 + 1] << 8) + recipe_name[i * 2] for i in range(8)}, # program name + **{727 - 1 + i: (recipe_barcode[i * 2 + 1] << 8) + recipe_barcode[i * 2] for i in range(12)}, # program associated bar-code "Test type": "Leak Test", "Test flags": 0b0110000001011100, "T0 - Pre-filling time": step.spec["pre_filling_time"], @@ -307,3 +323,34 @@ class TecnaMarpossProvasetT3(ModbusComponent): self.log.debug(str(spec)) for register, value in spec.items(): self.write(register, value) + + @db.connection_context() + def store_recipes(self, recipes): + if not self.ready: + QMessageBox.critical( + None, + "Impossibile salvare le ricette", + "La tecna non sembra essere pronta", + ) + return + recipes = [] + for recipe in list(Recipes.select().order_by(Recipes.name.asc())): + if recipe.spec["leak_1"]: + recipes.append([recipe, Steps.get_by_id(recipe.spec["available_steps"]["leak_1"])]) + # reverve last for our recipe control + if len(recipes) > max(self.max_program_number - 1, 0): + self.log.warning(f"too many recipes ({len(recipes)}), saving only first {max(self.max_program_number - 1, 0)}") + QMessageBox.warning( + None, + "Impossibile salvare tutte le ricette", + f"Troppe ricette ({len(recipes)}), saranno salvate solamente le prime {max(self.max_program_number - 1, 0)}", + ) + self._store_recipes_signal.emit(recipes[:max(self.max_program_number - 1, 0)]) + self._store_recipes_lock.acquire(max(self._store_recipes_lock.available(), 1)) + + def _store_recipes(self, recipes): + self._store_recipes_lock.release(1) + if len(recipes) > max(self.max_program_number - 1, 0): + self.log.warning(f"too many recipes ({len(recipes)}) saving only first {max(self.max_program_number - 1, 0)}") + for i, [recipe, step] in enumerate(recipes[:max(self.max_program_number - 1, 0)], start=1): + self.write_recipe(recipe, step, table=i) diff --git a/src/components/tecna_marposs_provaset_t3l_registers.py b/src/components/tecna_marposs_provaset_t3l_registers.py index b3d1a8f..0c2a814 100644 --- a/src/components/tecna_marposs_provaset_t3l_registers.py +++ b/src/components/tecna_marposs_provaset_t3l_registers.py @@ -170,6 +170,7 @@ registers = { "Reset test counter": [107 - 1, {"dt": "16bit_uint", }], # Write any U16 number to reset tests counters # ------------------------------------------------------------ + "Max number of programs": [20042 - 1, {"dt": "16bit_uint", }], "Language": [601 - 1, {"dt": "16bit_uint", "encoding": { "ITALIAN": 0, "ENGLISH": 1, @@ -199,9 +200,7 @@ registers = { 2: "BCD BASE 0, FROM DIGITAL INPUTS (PLC INTERFACE)", }, }], "Selected program": [603 - 1, {"dt": "16bit_uint", }], - # 1- n max programs - "Selected program": [603 - 1, {"dt": "16bit_uint", }], - # 1- n max programs + # 1-n max programs "Use programs or use products": [604 - 1, {"dt": "16bit_uint", }], # 0: the Start command will run the active program (see reg. 101 to set the program number) # 1: the Start command will run the active product (see reg. 101 to set the product number) diff --git a/src/components/tecna_marposs_provaset_t3p_registers.py b/src/components/tecna_marposs_provaset_t3p_registers.py index 1632d9f..e68d370 100644 --- a/src/components/tecna_marposs_provaset_t3p_registers.py +++ b/src/components/tecna_marposs_provaset_t3p_registers.py @@ -140,6 +140,7 @@ registers = { # Write 1 in the bit corresponding to the output to be deactivated "Reset test counter": [107 - 1, {"dt": "16bit_uint", }], # ------------------------------------------------------------ + "Max number of programs": [542 - 1, {"dt": "16bit_uint", }], "Language": [601 - 1, {"dt": "16bit_uint", "encoding": { "ITALIAN": 0, "ENGLISH": 1, diff --git a/src/main.py b/src/main.py index d0352ac..3470cd1 100644 --- a/src/main.py +++ b/src/main.py @@ -154,6 +154,13 @@ try: # self.main_window.steps_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Steps_Management())) # if "--steps-management" in sys.argv: # self.main_window.steps_management_a.trigger() + if "tecna_t3" in self.components and "--enable-saving-tecna-recipes" in sys.argv: + self.main_window.save_tecna_recipes_a.triggered.connect(self.components["tecna_t3"].store_recipes) + self.main_window.save_tecna_recipes_a.setVisible(True) + if "--save-tecna-recipes" in sys.argv: + self.main_window.save_tecna_recipes_a.trigger() + else: + self.main_window.save_tecna_recipes_a.setVisible(False) # OPEN LOGIN TAB self.open_login() # SHOW MAIN WINDOW diff --git a/src/ui/main_window/main_window.ui b/src/ui/main_window/main_window.ui index 853aa40..ae1f3d1 100644 --- a/src/ui/main_window/main_window.ui +++ b/src/ui/main_window/main_window.ui @@ -34,6 +34,7 @@ Amministrazione + @@ -87,6 +88,11 @@ Logout operatore + + + Salva ricette su Tecna + + diff --git a/src/ui/recipe_selection/recipe_selection.py b/src/ui/recipe_selection/recipe_selection.py index ecdfad9..0c70191 100755 --- a/src/ui/recipe_selection/recipe_selection.py +++ b/src/ui/recipe_selection/recipe_selection.py @@ -162,7 +162,7 @@ class Recipe_Selection(Widget): }, "resistance": { "scale": float(row.get("scala_resistenza", defaults["scala_resistenza"])), - "expected": float(row.get("R nominale", defaults["R nominale"]).replace(" ","").replace("Ω","")), + "expected": float(row.get("R nominale", defaults["R nominale"]).replace(" ", "").replace("Ω", "")), "tolerance": float(row.get("tolleranza_resistenza", defaults["tolleranza_resistenza"])), }, "screws": {