diff --git a/config/instruction_images/st-ten-10/pipe.gif b/config/instruction_images/st-ten-10/pipe.gif new file mode 100644 index 0000000..2e37902 Binary files /dev/null and b/config/instruction_images/st-ten-10/pipe.gif differ diff --git a/config/machine_settings/defaults.ini b/config/machine_settings/defaults.ini index fed355b..cf7d3c0 100644 --- a/config/machine_settings/defaults.ini +++ b/config/machine_settings/defaults.ini @@ -18,6 +18,7 @@ barcode_recipe_selection: absent ; vision_saver: absent ; vision: absent ; external_flush_blow: absent # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH +;pipe_cutter: absent [galaxy_camera] horizontal_resolution: 2448 diff --git a/config/machine_settings/st-ten-10.ini b/config/machine_settings/st-ten-10.ini index f33dd28..746a2c3 100644 --- a/config/machine_settings/st-ten-10.ini +++ b/config/machine_settings/st-ten-10.ini @@ -13,6 +13,7 @@ furness_controls: absent barcode_recipe_selection : absent digital_io: absent # used only for instruction images leak_disabled: active #disable the tecna_t3 and furness_controls from starting by setting the tester-component to None +pipe_cutter: present [archive_synchronizer] @@ -80,6 +81,13 @@ pressione_svuotamento: 100 canale_di_prova: 0 n_componenti: 1 tester_discharge_enable: yes +tagliatubi: x +lunghezza_corrugato: 100 +diametro_corrugato:21 [autotest_leak] enabled: false + +[pipe_cutter] +port: /dev/ttyUSB0 +baudrate: 38600 \ No newline at end of file diff --git a/src/components/__init__.py b/src/components/__init__.py index d42e8cf..6cc0717 100644 --- a/src/components/__init__.py +++ b/src/components/__init__.py @@ -13,6 +13,7 @@ from .usb_586x import USB_586x from .rfid_pn532 import RFID_PN532 from .furness_controls_leak_tester import FurnessControlsLeakTester from .brother_label_printer import BrotherLabelPrinter +from .pipe_cutter_component import PipeCutterComponent if "--vision" in sys.argv: from .galaxy_camera import GalaxyCamera from .neo_pixels import NeoPixels diff --git a/src/components/pipe_cutter_component.py b/src/components/pipe_cutter_component.py new file mode 100644 index 0000000..2022552 --- /dev/null +++ b/src/components/pipe_cutter_component.py @@ -0,0 +1,86 @@ +import logging +import time + +from .modbus_component import ModbusComponent + + +class PipeCutterComponent(ModbusComponent): + def __init__(self, config=None, name="pipe_cutter", period=1, lazy=True, paused=False, threaded=True): + """Initialize the Pipe Cutter Component.""" + super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded) + self.log = logging.getLogger(self.name) + self.current_total_length = None + self.current_od_of_pipe = None + self.machine_status = None + + def read_total_length(self): + """Read the total length (Register 4X30).""" + try: + self.current_total_length = self.read(register_address=30, data_type="16bit_uint") + self.log.info(f"Total length (Register 4X30): {self.current_total_length}") + return self.current_total_length + except Exception as e: + self.log.error(f"Failed to read total length (Register 4X30): {e}") + raise + + def read_od_of_pipe(self): + """Read the OD of the pipe (Register 4X60).""" + try: + self.current_od_of_pipe = self.read(register_address=60, data_type="16bit_uint") + self.log.info(f"OD of the pipe (Register 4X60): {self.current_od_of_pipe}") + return self.current_od_of_pipe + except Exception as e: + self.log.error(f"Failed to read OD of the pipe (Register 4X60): {e}") + raise + + def read_machine_status(self): + try: + self.machine_status = self.read(register_address=1,register=766 ,data_type="16bit_uint") + self.log.info(f"Machine status (Register 4X766): {self.machine_status}") + return self.machine_status + except Exception as e: + self.log.error(f"Failed to read machine status (Register 4X766): {e}") + raise + + def write_total_length(self, value): + try: + self.write(register_address=1,register=30, value=value, data_type="16bit_uint") + self.log.info(f"Wrote total length (Register 4X30): {value}") + except Exception as e: + self.log.error(f"Failed to write total length (Register 4X30): {e}") + raise + + def write_od_of_pipe(self, value): + try: + self.write(register_address=1,register=60, value=value, data_type="16bit_uint") + self.log.info(f"Wrote OD of pipe (Register 4X60): {value}") + except Exception as e: + self.log.error(f"Failed to write OD of pipe (Register 4X60): {e}") + raise + + def write_bit_with_delay(self, register_address, bit_position, delay_ms): + """ + Set a specific bit in a Modbus register, wait for a specified time, and reset it. + + :param register_address: The register address to write to. + :param bit_position: The bit position to modify (0-15). + :param delay_ms: The delay in milliseconds before resetting the bit to 0 . + """ + try: + # Step 1: Set the bit to 1 + current_value = self.read(register_address, data_type="16bit_uint") + new_value = current_value | (1 << bit_position) # Set the bit + self.write(register_address, new_value, data_type="16bit_uint") + self.log.info(f"Set bit {bit_position} in register {register_address} to 1") + + # Step 2: Wait for the specified delay + time.sleep(delay_ms / 1000) # Convert milliseconds to seconds + + # Step 3: Reset the bit to 0 + current_value = self.read(register_address, data_type="16bit_uint") + new_value = current_value & ~(1 << bit_position) # Clear the bit + self.write(register_address, new_value, data_type="16bit_uint") + self.log.info(f"Reset bit {bit_position} in register {register_address} to 0") + except Exception as e: + self.log.error(f"Failed to set and reset bit {bit_position} in register {register_address}: {e}") + raise \ No newline at end of file diff --git a/src/lib/helpers/recipe_manager.py b/src/lib/helpers/recipe_manager.py index 7b6aa79..2ccfcf2 100644 --- a/src/lib/helpers/recipe_manager.py +++ b/src/lib/helpers/recipe_manager.py @@ -63,7 +63,12 @@ def read_steps(row, config, defaults=None, unsupported_steps=None): "screws": { "quantity": row.get("viti", defaults["viti"]), }, - "instruction": {}, # Empty placeholder for future extensions + "instruction": {}, + "pipe_cutter": { + "lenght": row.get("lunghezza_corrugato", defaults["lunghezza_corrugato"]), + "diameter": row.get("diametro_corrugato", defaults["diametro_corrugato"]), + }, + # Empty placeholder for future extensions "leak_1": { "pre_filling_time": safe_parse(row.get("tempo_pre_riempimento", defaults["tempo_pre_riempimento"])), "pre_filling_pressure": safe_parse( @@ -228,6 +233,7 @@ def import_recipes(config, csv_path=None, defaults=None, unsupported_steps=None, unsupported_steps or []), "instruction_extra": len(row.get("istruzione_abilitata_extra", defaults[ "istruzione_abilitata_extra"])) and "instruction_extra" not in (unsupported_steps or []), + "pipe_cutter": len(row.get("tagliatubi", defaults["tagliatubi"])) and "pipe_cutter" not in (unsupported_steps or []), "leak_1": len( row.get("prova_tenuta_abilitata", defaults["prova_tenuta_abilitata"])) and "leak_1" not in ( unsupported_steps or []), diff --git a/src/main.py b/src/main.py index 7b385da..9b53380 100644 --- a/src/main.py +++ b/src/main.py @@ -69,7 +69,7 @@ try: # IMPORT PROJECT ONLY AFTER SETTING UP SIGNAL, FAULTHANDLER AND LOGGING from components import (ArchiveSynchronizer, Multicomp730424, Os_Label_Printer, RemoteAPI, - TecnaMarpossProvasetT3, FurnessControlsLeakTester, TecnaScrewdriver, USB_586x, RFID_PN532,BrotherLabelPrinter) + TecnaMarpossProvasetT3, FurnessControlsLeakTester, TecnaScrewdriver, USB_586x, RFID_PN532,BrotherLabelPrinter,PipeCutterComponent) from lib.db import Users from lib.helpers import ConfigReader from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot @@ -115,6 +115,7 @@ try: "digital_io": {"c": USB_586x, "k": {"paused": True}}, "digital_io_flush_blow": {"c": USB_586x, "k": {"paused": True}}, "fixture_id": {"c": RFID_PN532, "k": {"paused": False, "lazy": False}}, + "pipe_cutter": {"c": PipeCutterComponent, "k": {"paused": False}}, } # VISION COMPONENT IS OPTIONAL AND DISABLED BY DEFAULT if "--vision" in sys.argv: diff --git a/src/test/modbus_read_data.py b/src/test/modbus_read_data.py index 18e68a8..ca7c1a5 100644 --- a/src/test/modbus_read_data.py +++ b/src/test/modbus_read_data.py @@ -1,41 +1,64 @@ import serial -from pymodbus.client.sync import ModbusSerialClient as ModbusClient +from pymodbus.client import ModbusSerialClient as ModbusClient from pymodbus.exceptions import ModbusIOException +import logging import time -def read_modbus_data(client, starting_register, register_count): + + +def read_register(client, register_address, count=1): """ Reads data from the Modbus server. :param client: An instance of ModbusClient - :param starting_register: The address of the register to start reading from - :param register_count: Number of registers to read + :param register_address: The address of the register to read + :param count: Number of registers to read :return: List of register values or None if there was an error """ try: - read_data = client.read_holding_registers(starting_register, count=register_count) - if isinstance(read_data, ModbusIOException): - print("Error: ModbusIOException occurred during read operation.") + result = client.read_holding_registers(register_address, count=count, slave=1) + if result.isError(): + print(f"Error reading register {register_address}: {result}") return None - else: - return read_data.registers + return result.registers except Exception as e: - print(f"Error: {e}") + print(f"Error reading register {register_address}: {e}") return None +def write_register(client, register_address, value): + """ + Writes data to a Modbus register. + + :param client: An instance of ModbusClient + :param register_address: The address of the register to write + :param value: The value to write to the register + :return: True if the write was successful, False otherwise + """ + try: + result = client.write_register(register_address, value, slave=1) + if result.isError(): + print(f"Error writing value {value} to register {register_address}: {result}") + return False + return True + except Exception as e: + print(f"Error writing value {value} to register {register_address}: {e}") + return False + + def main(): # Modbus client configuration client = ModbusClient( method="rtu", - port="/dev/ttyUSB0", # Specify the correct port for your serial connection + port="/dev/ttyUSB0", # Ensure the correct port for your setup stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, baudrate=38400, timeout=1, # Timeout in seconds - strict=False + strict=False, + slave=1 ) # Attempt to connect to the Modbus server @@ -45,24 +68,32 @@ def main(): print("Failed to connect to Modbus client.") return - # Starting the data read loop try: - starting_register = 1 # Define the starting register address - register_count = 10 # Define the number of registers to read + # Define the register address and value + register_address = 30 # Address to read/write + write_value = 1100 # Value to write to the register - print("Starting data read loop...") - while True: - data = read_modbus_data(client, starting_register, register_count) - if data: - # Print read data - for i, value in enumerate(data): - print(f"Register {starting_register + i}: {value}") - else: - print("Failed to read data from Modbus server.") + # Step 1: Read the register value + print(f"Reading register {register_address}...") + read_data = read_register(client, register_address) + if read_data is not None: + print(f"Register {register_address} value before write: {read_data[0]}") + + # Step 2: Write a value to the register + print(f"Writing value {write_value} to register {register_address}...") + if write_register(client, register_address, write_value): + print(f"Successfully wrote value {write_value} to register {register_address}.") + else: + print(f"Failed to write value {write_value} to register {register_address}.") + + # Step 3: Read the register again to confirm the write + print(f"Reading register {register_address} after write...") + read_data = read_register(client, register_address) + if read_data is not None: + print(f"Register {register_address} value after write: {read_data[0]}") - time.sleep(1) # Wait 1 second before the next read (adjust as necessary) except KeyboardInterrupt: - print("\nStopping read loop...") + print("\nStopping operation...") finally: client.close() print("Modbus client connection closed.") diff --git a/src/ui/__init__.py b/src/ui/__init__.py index 8388ade..4ff2203 100644 --- a/src/ui/__init__.py +++ b/src/ui/__init__.py @@ -30,6 +30,7 @@ from .recipes_management import Recipes_Management from .resistance_step_editor import Resistance_Step_Editor from .screws_step_editor import Screws_Step_Editor from .instruction_step_editor import Instruction_Step_Editor +from .pipe_cutter_step_editor import Pipe_Cutter_Step_Editor from .steps_management import Steps_Management from .test import Test from .test_admin_permission import Test_Admin_Permission diff --git a/src/ui/pipe_cutter_step_editor/__init__.py b/src/ui/pipe_cutter_step_editor/__init__.py new file mode 100644 index 0000000..d9266dd --- /dev/null +++ b/src/ui/pipe_cutter_step_editor/__init__.py @@ -0,0 +1 @@ +from .pipe_cutter_step_editor import Pipe_Cutter_Step_Editor diff --git a/src/ui/pipe_cutter_step_editor/pipe_cutter_step_editor.py b/src/ui/pipe_cutter_step_editor/pipe_cutter_step_editor.py new file mode 100644 index 0000000..27ac7c0 --- /dev/null +++ b/src/ui/pipe_cutter_step_editor/pipe_cutter_step_editor.py @@ -0,0 +1,11 @@ +from ui.editor import Editor + + +class Pipe_Cutter_Step_Editor(Editor): + def __init__(self, action=None, cell_widget=None): + super().__init__(action=action, cell_widget=cell_widget) + self.spec.update({ + "lenght": self.lenght_le, + "diameter":self.diameter_le + + }) diff --git a/src/ui/pipe_cutter_step_editor/pipe_cutter_step_editor.ui b/src/ui/pipe_cutter_step_editor/pipe_cutter_step_editor.ui new file mode 100644 index 0000000..e14f823 --- /dev/null +++ b/src/ui/pipe_cutter_step_editor/pipe_cutter_step_editor.ui @@ -0,0 +1,113 @@ + + + Pipe_Cutter_Step_Editor + + + + 0 + 0 + 1004 + 300 + + + + Connector Step Editor + + + + + + + 0 + 0 + + + + + 10 + 50 + false + + + + Specifica Taglia Corrugati + + + + + 20 + 40 + 131 + 20 + + + + Lunghezza Corrugato + + + + + + 160 + 30 + 141 + 36 + + + + + + + 20 + 80 + 121 + 20 + + + + Diametro Corrugato + + + + + + 160 + 70 + 141 + 36 + + + + + + + 320 + 40 + 101 + 20 + + + + mm + + + + + + 320 + 80 + 101 + 20 + + + + mm + + + + + + + + + diff --git a/src/ui/recipe_selection/recipe_selection.py b/src/ui/recipe_selection/recipe_selection.py index b5c4a26..b3ad0e0 100755 --- a/src/ui/recipe_selection/recipe_selection.py +++ b/src/ui/recipe_selection/recipe_selection.py @@ -96,6 +96,8 @@ class Recipe_Selection(Widget): 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, + "instruction_extra": len(self.config.get("recipes_defaults", noner)["istruzione_abilitata_extra"]) and "instruction_extra" not in self.unsupported_steps, + "pipe_cutter": len(self.config.get("recipes_defaults", noner)["tagliatubi"]) and "pipe_cutter" 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, "leak_2": len(self.config.get("recipes_defaults", noner)["prova_tenuta_abilitata_2"]) and "leak_2" not in self.unsupported_steps, "vision": len(self.config.get("recipes_defaults", noner)["test_visione_abilitato"]) and "vision" not in self.unsupported_steps, @@ -222,6 +224,10 @@ class Recipe_Selection(Widget): "quantity": row.get("viti", defaults["viti"]) }, "instruction": {}, + "pipe_cutter": { + "length": row.get("lunghezza_corrugato", defaults["lunghezza_corrugato"]), + "diameter": row.get("diametro", defaults["diametro"]), + }, "leak_1": { "pre_filling_time": int(float(row.get("tempo_pre_riempimento", defaults["tempo_pre_riempimento"]))), "pre_filling_pressure": int(float(row.get("pressione_pre_riempimento", defaults["pressione_pre_riempimento"]))), 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 42f22da..d993be1 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 @@ -5,6 +5,7 @@ from ui.count_step_editor import Count_Step_Editor from ui.editor import Editor from ui.helpers import replace_widget from ui.leak_step_editor import Leak_Step_Editor +from ui.pipe_cutter_step_editor import Pipe_Cutter_Step_Editor from ui.print_step_editor import Print_Step_Editor from ui.resistance_step_editor import Resistance_Step_Editor from ui.screws_step_editor import Screws_Step_Editor @@ -95,6 +96,13 @@ class Recipe_Spec_And_Step_Editor(Editor): "editor": Print_Step_Editor(), "tab": self.print_t, }, + "pipe_cutter": { + "type": "pipe_cutter", + "enable": self.pipe_cutter_enabled_cb, + "widget": "pipe_cutter_editor_w", + "editor": Pipe_Cutter_Step_Editor(), + "tab": self.pipe_cutter_t, + }, } for step_name in unsupported_steps: self.steps_map.get(step_name, {})["hidden"] = True 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 6852f91..6c4724f 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 @@ -19,18 +19,18 @@ Recipe Spec And Step Editor - - - - Resetta configurazione -Fasi di Test - - - Salva configurazione +Fasi di Test + + + + + + + Resetta configurazione Fasi di Test @@ -298,6 +298,56 @@ Fasi di Test + + + Taglia Tubi + + + + + + Qt::Horizontal + + + + 572 + 20 + + + + + + + + Qt::Horizontal + + + + 572 + 20 + + + + + + + + Fase Abilitata + + + + + + + + 0 + 0 + + + + + + Montaggio extra diff --git a/src/ui/test/test.py b/src/ui/test/test.py index 1a045d4..ac3ef25 100755 --- a/src/ui/test/test.py +++ b/src/ui/test/test.py @@ -20,6 +20,7 @@ from ui.test_count import Test_Count from ui.test_count_end import Test_Count_End from ui.test_fail import Test_Fail from ui.test_instructions import Test_Instructions +from ui.test_pipe_cutter import Test_Pipe_Cutter from ui.test_leak import Test_Leak from ui.test_resistance import Test_Resistance from ui.test_screws import Test_Screws @@ -82,6 +83,7 @@ class Test(Widget): "resistance": {"multicomp", }, "leak_1": {self.tester_component, }, "leak_2": {self.tester_component, }, + "pipe_cutter": {"pipe_cutter"}, "vision": {("uvc_camera", "galaxy_camera",), "vision", "vision_saver", }, # "neo_pixels", }, "print": {"label_printer_2"} if self.config["hardware_config"]["label_printer"] != "present" else {"label_printer"}, } @@ -121,6 +123,7 @@ class Test(Widget): "flush": Test_Assembly(img_path=None, text=u"SCARICO ARIA IN CORSO - ATTENDERE...", widget=Test_Warning_Img(components=self.components, recipe=self.recipe, step=self.step)), "instruction": Test_Assembly(img_path=None, text=u"ESEGUIRE LE OPERAZIONI DI MONTAGGIO INDICATE IN FIGURA", widget=Test_Instructions(config=self.config,components=self.components, recipe=self.recipe, bench_name=self.config.machine_id, step=self.step)), + "pipe_cutter": Test_Assembly(img_path=None, text=u"ATTENZIONE TAGLIO CORRUGATOIN CORSO",widget=Test_Pipe_Cutter(config=self.config, components=self.components,recipe=self.recipe, bench_name=self.config.machine_id,step=self.step)), "instruction_extra": Test_Assembly(img_path=None, text=u"ESEGUIRE LE OPERAZIONI DI MONTAGGIO EXTRA INDICATE IN FIGURA", widget=Test_Instructions(config=self.config, components=self.components,recipe=self.recipe, bench_name=self.config.machine_id,step=self.step)), "piece_removal": Test_Assembly(img_path=None, text=u"RIMUOVERE IL PEZZO APRENDO TUTTE LE CHIUSURE", @@ -428,6 +431,9 @@ class Test(Widget): if step.spec["warning_img"]: steps.insert(i, Step(step_type="warning_img", spec={"warning_img": step.spec["warning_img"]})) skip.add(i + 1) + if step.step_type in "pipe_cutter": + self.pipe_cutter_step = step + if "assembly" in step.spec: if step.spec["assembly"]: steps.insert(i, Step(step_type="instructions", spec={})) diff --git a/src/ui/test_pipe_cutter/__init__.py b/src/ui/test_pipe_cutter/__init__.py new file mode 100644 index 0000000..a6ee3d3 --- /dev/null +++ b/src/ui/test_pipe_cutter/__init__.py @@ -0,0 +1 @@ +from .test_pipe_cutter import Test_Pipe_Cutter diff --git a/src/ui/test_pipe_cutter/test_pipe_cutter.py b/src/ui/test_pipe_cutter/test_pipe_cutter.py new file mode 100644 index 0000000..5f62bb4 --- /dev/null +++ b/src/ui/test_pipe_cutter/test_pipe_cutter.py @@ -0,0 +1,86 @@ +from PyQt5.QtGui import QMovie +import logging +from ui.test_test import Test_Test +from components import PipeCutterComponent +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +class Test_Pipe_Cutter(Test_Test): + """ + A class to manage and operate a pipe cutter machine in a test environment. + """ + + def __init__(self, config, components, recipe=None, run_once=False, + reset_on_start=False, enable_override=False, bench_name="generic", step=None,): + super().__init__(components=components, recipe=recipe, step=None, run_once=run_once, + reset_on_start=reset_on_start, enable_override=enable_override,) + self.bench_name = bench_name + self.cutter = PipeCutterComponent() + self.current_cut_length = 0.0 + self.max_cut_length = config.get("max_cut_length", 10.0) + self.movie = QMovie(config.get("config/instruction_images/st-ten-10/pipe.gif ")) # Animation Path + self.current_status = None + + def start(self, recipe=None, step=None, pieces=None): + if step is not None : + self.start_cutting() + self.display_cutting_animation(True) + self.stop_cutting() + + def start_cutting(self,recipe=None,step=None): + """ + Start the pipe cutting process and activate the pipe cutter component. + """ + self.current_status = self.cutter.read_machine_status() + if self.current_status == 102 : # ready for operation + try: + self.reset_machine() + self.cutter.write_total_length(self.recipe.spec.get("length", None)) + self.cutter.write_od_of_pipe(self.recipe.spec.get("diameter", None)) + self.cutter.write_bit_with_delay(600,0,100) + except Exception as e: + logger.error(f"Failed to start the pipe cutting process: {e}") + else: + try: + self.cutter.write_bit_with_delay(600, 1, 100) # resetting + except Exception as e: + logger.error(f"Failed to reset the pipe cutting process: {e}") + + def stop_cutting(self): + """ + Stop the pipe cutting process and deactivate the pipe cutter component. + """ + try: + self.current_status = self.cutter.read_machine_status() + if self.current_status in(106,107): + + self.cutter.write_bit_with_delay(600, 2, 100) + self.reset_machine() + except Exception as e: + logger.error(f"Failed to stop the pipe cutting process: {e}") + + def reset_machine(self): + """ + Reset the pipe cutter machine to its initial state. + """ + try: + self.cutter.write_bit_with_delay(600, 1, 100) + except Exception as e: + logger.error(f"Failed to reset the pipe cutter machine: {e}") + + def display_cutting_animation(self, show: bool): + """ + Show or hide the cutting animation GIF. + + Args: + show (bool): Whether to display or stop the animation. + """ + if show: + self.pipe_gif.setVisible(True) + self.movie.start() + logger.info("Cutting animation started.") + else: + self.movie.stop() + self.pipe_gif.setVisible(False) + logger.info("Cutting animation stopped.") diff --git a/src/ui/test_pipe_cutter/test_pipe_cutter.ui b/src/ui/test_pipe_cutter/test_pipe_cutter.ui new file mode 100644 index 0000000..3a84625 --- /dev/null +++ b/src/ui/test_pipe_cutter/test_pipe_cutter.ui @@ -0,0 +1,71 @@ + + + Test_Warning_Img + + + + 0 + 0 + 1657 + 922 + + + + Test Count End + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 20 + 75 + true + + + + TAGLIA CORRUGATO + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + 0 + 0 + + + + + + + + + + + + + + +