From 464d8d532ee0271b2601b4425e126688bf5ce172 Mon Sep 17 00:00:00 2001 From: st-ten-9 Date: Fri, 13 Oct 2023 17:52:41 +0200 Subject: [PATCH] fco730 alpha --- .../label_designs/SATIL/R5_30x17_203dpi.nlbl | Bin 3496 -> 3749 bytes .../st-ten-9/R5_30x17_203dpi.prn | 13 +- config/machine_settings/defaults.ini | 2 +- config/machine_settings/st-ten-1-linux.ini | 2 +- config/machine_settings/st-ten-2-linux.ini | 2 +- config/machine_settings/st-ten-2.ini | 2 +- config/machine_settings/st-ten-3.ini | 2 +- config/machine_settings/st-ten-8.ini | 2 +- config/machine_settings/st-ten-9.ini | 14 +- open_osk.bat | 1 + .../furness_controls_fco730_registers.py | 13 +- .../furness_controls_leak_tester.py | 203 +++++++++++------- src/components/tecna_marposs_provaset_t3.py | 2 +- src/ui/about/about.ui | 20 +- src/ui/imgs/r5.png | Bin 0 -> 12091 bytes src/ui/login/login.py | 2 +- src/ui/recipe_selection/recipe_selection.py | 9 +- src/ui/test/test.py | 14 +- src/ui/test_leak/test_leak.py | 6 +- src/ui/test_leak/test_leak.ui | 47 +++- 20 files changed, 231 insertions(+), 125 deletions(-) create mode 100644 open_osk.bat create mode 100644 src/ui/imgs/r5.png diff --git a/config/label_designs/SATIL/R5_30x17_203dpi.nlbl b/config/label_designs/SATIL/R5_30x17_203dpi.nlbl index 2b3be99d5a2517cb726d8d464e065a4bb4cbb4a7..50a477a778d470a69ac19bde0896ba0f04ff5730 100644 GIT binary patch literal 3749 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 F_ixt;;PwCj literal 3496 zcmb`KRa6x07KUeF7*eDe8MN)DVTd6GK|-W+M!FjWB&7SNq@`nMew9X$5-DjA z7+PA6|G7A89oIT{XMbz$cYPP%_g?IM@w_@3xF9M35by$^@J87v%%J|xkq7|jwgUiY z0fGQ!SCq5mE3}}lxVfm1x3HwSh>)nYn>{cS|MwGlC0qgk5r7%+PXPfC0LN}~zthDW z@J~gPEI+VFP#Y#qu=OBs_M`N$doFIkj9Sjo?|2H0eT=qY#Tt8Jv^X zy(xYSp+LYjRag-df#Rhsgy+Jep0fN!&DOe)iGnJe?I%wa$8+sYLyA{z?g#Rgn&d_p z#OJ$1{f$uu)VO`aW?E%cm`@s5@wAaD8Hv3!ZJ2G_;Cme88i9gI(m(fZB_r1KA2_(E4jtcJyFq(ytCv<2Fls4EIAY!ghCPPR!J`u|1IdKsu zsZQp22t`+d=y`8t%Pn_K(fyI`4uP~a73V)MIEeR6JP~_5u;lv#F$;5hPZHP0sNQ`n z#Odbc^TV7!ZmX?iS$Gt6mGi5Ryl0_pQ`D`O@`csPmFF6gi@%2_gY#A(1LBEbh?|$A?BpIubm08Hx1HN=;qhBg` zh7Lw?C9k?<+nGzx)7p;Be*AuXmoCs$_(qy)h2#9Xs&vt_N$g2G| z&KZU)JUysNdMUnTZSr0VUsP}$1kI6a$;HjP8X!6Y#RV;umO@@~iyDFEn3Kg=abmft zxMOMU%X}nOLsV7;xT~UWDta6rl7uXm6Kd^Xon2&SPr!WnTE%axXX#3t1X|p zEy?kL&Z|?p*FEhYPRwD${mw_&eYqfg~~1xk+C#qpLzEWV9)6braDX(M&vYClyCNBcQroCuSffxCx>Dn`Aj)f=>*ajNE? zjU_4&n}5LRU!3IHrA~ytc|T>Vp{p~il)^0Abxvf;p) zUo$f#ZtA8VjFtAgn;XYbRZ-PpuwRJM)VJ+pETWQ!7oKIrq;o-Gtw@hXP^a*?XY*aF zH~KQH;bo3y_r?Q;lKevHwn22}g1BB+0-`3LW(ydSv=^ow8)1O>f+`OV4)S4Or%X0| zM)g`z>nLDNZgJP`);!4}lY}pa=ip7V9#m3Wp~z*qX!SJoLOlH|LR))Y+l~lPMoDJxfbStsogvlg7u9suw>?( zU3-`ft8LvzJrrGp|2$L19q-oK7i(OWY3!k+fKpv$y;VvRn;wmn%u0}HfB{hCDUU!S zMS_@v4>8J`S2|y9dCxxhGWJ}N`MFbH5H_$Bw8 zF2O(U5r&|9b&bIJN=P87NYN45XNGakTzocU?FA@)GhAjrkl+Z@WEa|P{(CY$6*pI3Bal9pu{oLIwQrBaB7aNQ-|X=U$kI5d7E zcN;~8-=NePur99D!rQ?4BS#sR@^o{I(6WhnU+0K?j3_fx{A(JFG(w#sno$RzJK3Js& zjm5mcC`q*%x)bnpTq8l2UWGPa$7T%7!coVV4Q)2+~I)MF>*rxLbeVzXz<5{X)ri`D_M7%(Ft$gWg z_(6=ziZi?4ujZ-5X(A-it9|xp*o)W1!?f)5kZ@01HbA=WY;Md7CiG>i0eIq>h@(C)oFH zu4iYt=wLgER6=?$;RK5o!u}+Gr_bDsc7lU+kF5d}qvz;rp0Kf_#TL_7ZskYx4&KmcGD2LPb@jkAAXtN_}{#ruD-EQE3F-z@v5 z@<8JzO*S}}58#g_VyGr$m$P?Q8`mtK_%Oqi7pzDd2qZ$O`np&jOx+6 z^G=?gR{8#!`A0XXE7z2YOLD$^DZfX0UnJmT+A-SHTKf5({_WVKL)FyEr7yDubt8JY zLmQfbG_fciS_za`7!Hs>!%1E%sSU!xv*^MV7D^{M6F++|w8eCkB^FF}sw^9V8ph{lb#(xn2sOLKMuu>hui0#f)^1d&w4~Cv`R#AY=))PZJeYrU+ zO$>*aP)sBu1Q(q5E2Y2^IvPM6{@;`QUvcH%N#sB6{}W#R^!#(D{$mID{5v@PA2v)! T0}uSqr#QdQ#&4}A`RDd8WNJht diff --git a/config/label_templates/st-ten-9/R5_30x17_203dpi.prn b/config/label_templates/st-ten-9/R5_30x17_203dpi.prn index e362bad..4e45b02 100644 --- a/config/label_templates/st-ten-9/R5_30x17_203dpi.prn +++ b/config/label_templates/st-ten-9/R5_30x17_203dpi.prn @@ -21,11 +21,12 @@ ^PW256 ^LL144 ^LS0 -^FT29,119^BQN,2,3 -^FH\^FDLA,{PART}{SN5}{DATE}{TIME}^FS -^FT237,104^A0I,23,23^FH\^CI28^FD{PART}^FS^CI27 -^FT237,75^A0I,23,23^FH\^CI28^FDNum:{SN5}^FS^CI27 -^FT237,47^A0I,23,23^FH\^CI28^FD{DATE}^FS^CI27 -^FT237,18^A0I,23,23^FH\^CI28^FD{TIME}^FS^CI27 +^FT156,132^BQN,2,3 +^FH\^FDLA,{PART}_{SN5}_{DATE}_{TIME}^FS +^FT61,47^A0N,23,23^FH\^CI28^FD{PART}^FS^CI27 +^FT19,72^A0N,23,23^FH\^CI28^FDNum:{SN5}^FS^CI27 +^FT19,97^A0N,23,23^FH\^CI28^FD{DATE}^FS^CI27 +^FT19,122^A0N,23,23^FH\^CI28^FD{TIME}^FS^CI27 +^FO19,21^GFA,169,248,8,:Z64:eJxFz7ENAyEMBdCPrnCZEVgjRQQrUaY46RjtRmGElFec4vgbrNA82Rhji+qAnax60ar6pbulaAOkT7dzmsIxBX0v7X3Y2+zrRv656trf6BP9/T/rl+kLopyjQG6fs28fKgMeW1SoRV6Pyis7j56i0BdLa0Ec7g8asjdJ:20D6 ^PQ1,0,1,Y ^XZ diff --git a/config/machine_settings/defaults.ini b/config/machine_settings/defaults.ini index 971177b..c63aa8d 100644 --- a/config/machine_settings/defaults.ini +++ b/config/machine_settings/defaults.ini @@ -124,7 +124,7 @@ warning_img: pid_mode: 0 # 0=FAST 1=MEDIUM 2=SLOW 4 = FIXED 5 = AUTOMATIC 6 = FLOW 7 = LEAK WITH FLOW pid_level: 1 pid_speed: 1 -tecna_discharge_enable: no +tester_discharge_enable: no tempo_pre_riempimento: 0 pressione_pre_riempimento: 1000 diff --git a/config/machine_settings/st-ten-1-linux.ini b/config/machine_settings/st-ten-1-linux.ini index 9a43767..ca9bcc0 100644 --- a/config/machine_settings/st-ten-1-linux.ini +++ b/config/machine_settings/st-ten-1-linux.ini @@ -43,7 +43,7 @@ pressione_di_test_delta_massimo: 30 tempo_svuotamento: 1 pressione_svuotamento: 100 canale_di_prova: 0 -tecna_discharge_enable: yes +tester_discharge_enable: yes [autotest_leak] enabled: true diff --git a/config/machine_settings/st-ten-2-linux.ini b/config/machine_settings/st-ten-2-linux.ini index 7b91d90..f08d687 100644 --- a/config/machine_settings/st-ten-2-linux.ini +++ b/config/machine_settings/st-ten-2-linux.ini @@ -48,7 +48,7 @@ pressione_di_test_delta_massimo: 30 tempo_svuotamento: 1 pressione_svuotamento: 100 canale_di_prova: 0 -tecna_discharge_enable: yes +tester_discharge_enable: yes [autotest_leak] enabled: true diff --git a/config/machine_settings/st-ten-2.ini b/config/machine_settings/st-ten-2.ini index 7f25cae..66f2020 100644 --- a/config/machine_settings/st-ten-2.ini +++ b/config/machine_settings/st-ten-2.ini @@ -48,7 +48,7 @@ pressione_di_test_delta_massimo: 30 tempo_svuotamento: 1 pressione_svuotamento: 100 canale_di_prova: 0 -tecna_discharge_enable: yes +tester_discharge_enable: yes [autotest_leak] enabled: true diff --git a/config/machine_settings/st-ten-3.ini b/config/machine_settings/st-ten-3.ini index 11fd7f8..115ad9b 100644 --- a/config/machine_settings/st-ten-3.ini +++ b/config/machine_settings/st-ten-3.ini @@ -39,7 +39,7 @@ pressione_di_test_delta_massimo: 30 tempo_svuotamento: 1 pressione_svuotamento: 100 canale_di_prova: 0 -tecna_discharge_enable: yes +tester_discharge_enable: yes [autotest_leak] enabled: true diff --git a/config/machine_settings/st-ten-8.ini b/config/machine_settings/st-ten-8.ini index 0d7936a..4f581f2 100644 --- a/config/machine_settings/st-ten-8.ini +++ b/config/machine_settings/st-ten-8.ini @@ -52,7 +52,7 @@ label_template_field: modello_etichetta description_field: descrizione [recipes_defaults] -tecna_discharge_enable: yes +tester_discharge_enable: yes dimensione_lotto_abilitata: x tempo_pre_riempimento: 0 pressione_pre_riempimento: 1000 diff --git a/config/machine_settings/st-ten-9.ini b/config/machine_settings/st-ten-9.ini index 5a18ece..f16601c 100644 --- a/config/machine_settings/st-ten-9.ini +++ b/config/machine_settings/st-ten-9.ini @@ -1,8 +1,8 @@ [machine] -description = ST-TEN-9 SATIL SRL - BANCO COLLAUDO TUBI R5 +description = ST-TEN-9 SATIL SRL - BANCO PROVA TENUTA 10 BAR [hardware_config] -archive_synchronizer: present +archive_synchronizer: absent label_printer: present remote_api: absent tecna_t3: absent @@ -47,8 +47,8 @@ label_template_field: modello_etichetta description_field: descrizione [recipes_defaults] -tecna_discharge_enable: yes -dimensione_lotto_abilitata: x +tester_discharge_enable: yes +dimensione_lotto_abilitata: tempo_pre_riempimento: 0 pressione_pre_riempimento: 0 tempo_riempimento: 5 @@ -62,17 +62,17 @@ pressione_di_test_delta_massimo: 20 # -mbar tempo_svuotamento: 1 pressione_svuotamento: 100 canale_di_prova: 1 -modello_etichetta: satil_30x17.prn +modello_etichetta: R5_30x17_203dpi.prn [autotest_leak] enabled: true pre_filling_time: 0 -pre_filling_pressure: 1000 +pre_filling_pressure: 0 filling_time: 10 settling_time: 10 settling_pressure_min_percent: 5 settling_pressure_max_percent: 5 -test_pressure: 7000 +test_pressure: 5000 test_time: 10 test_pressure_qpos: 10 #Q+ Upper test leak limit test_pressure_qneg: 30 #Q- Lower test leak limit diff --git a/open_osk.bat b/open_osk.bat new file mode 100644 index 0000000..0816ab6 --- /dev/null +++ b/open_osk.bat @@ -0,0 +1 @@ +osk diff --git a/src/components/furness_controls_fco730_registers.py b/src/components/furness_controls_fco730_registers.py index a8fd113..381f29a 100644 --- a/src/components/furness_controls_fco730_registers.py +++ b/src/components/furness_controls_fco730_registers.py @@ -59,14 +59,23 @@ registers = { '4': 'ATTESA RESET', '5': 'ATTESA START', '6': 'ERRORE', - '7': 'pressure_high', - '8': 'pressure_low', + '7': 'PRESSIONE ALTA', + '8': 'PRESSIONE BASSA', '9': 'jig_delay', '10': 'prefilling', '11': 'SCARICO', '12': 'reserverd', '13': 'sequence_delay', '14': 'jig_open' + }, + "status_result":{ + '0': 'PASSED', + '1': 'NEGATIVE FAIL', + '2': 'POSITIVE FAIL', + '3': 'RESERVED', + '4': 'PRESSURE GROSS FAIL', + '5': 'RESET DURING TEST', + '6': 'GLOBAL FAIL', } } diff --git a/src/components/furness_controls_leak_tester.py b/src/components/furness_controls_leak_tester.py index 578645e..7547209 100644 --- a/src/components/furness_controls_leak_tester.py +++ b/src/components/furness_controls_leak_tester.py @@ -3,19 +3,22 @@ import sys import time from collections import OrderedDict +from PyQt5.QtCore import QMutex + from components.component import Component from components.furness_controls_fco730_registers import registers as fco730_registers from components.furness_controls_fco780_registers import registers as fco780_registers + if "--sim-furness-controls" in sys.argv: from components.dummies.serial import serial else: import serial -ETX=b'\x03' -EOT=b'\x04' -ENQ=b'\x05' -ACK=b'\x06' -NACK=b'\x15' +ETX = b'\x03' +EOT = b'\x04' +ENQ = b'\x05' +ACK = b'\x06' +NACK = b'\x15' class FurnessControlsLeakTester(Component): @@ -29,14 +32,15 @@ class FurnessControlsLeakTester(Component): self.timeout = None self.parity = None self.conn = None + self.lock = QMutex() self.stopbits = None self.baudrate = None self.port = None self.model = None self.settings = None self.commands = None - self.id1=b'0' - self.id2=b'1' + self.id1 = b'0' + self.id2 = b'1' def config_changed(self): super().config_changed() @@ -77,22 +81,30 @@ class FurnessControlsLeakTester(Component): @Component.reconfig_on_error def _get(self): # READ INFO - current_status=self.get_status() + current_status = self.get_status() info = { - "Real time test pressure output":current_status["pressure_reading"], - "Real time differential pressure output":0, - "Real time pressure line regulator":0, - "Active alarm flags":0, - "Active test program number":0, - "Running test: active phase":current_status["current_stage"], - "Running test: measured leak":current_status["leak_reading"], - "Running test: test type":0, - "Running test: sequence index":0, - "Digital inputs status (mask)":0, + "Real time test pressure output": current_status["pressure_reading"], + "Real time differential pressure output": 0, + "Real time pressure line regulator": 0, + "Active alarm flags": 0, + "Active test program number": 0, + "Running test: active phase": current_status["current_stage"], + "Running test: measured leak": current_status["leak_reading"], + "Running test: test type": 0, + "Running test: sequence index": 0, + "Digital inputs status (mask)": 0, } + + if current_status['new_result_available'] == '1': # NEW TEST RESULT AVAILABLE + last_test_result = self.get_last_result() # READ RESULT TO RESET AVAILABLE FLAG + info.update({"Running test: result": last_test_result['status'], + "Running test: filling pressure": current_status["pressure_reading"], + "Running test: pressure at the end of settling": current_status["pressure_reading"], + + }) for round_me in ["measured leak"]: if round_me in info.keys(): - info.update({round_me:float(f"{info[round_me]:.2f}")}) + info.update({round_me: float(f"{info[round_me]:.2f}")}) self.log.debug(str(info)) super()._get([info]) @@ -101,63 +113,99 @@ class FurnessControlsLeakTester(Component): self.send_command("start_test") def stop_test(self): - self.log.warning("stopping test") - self.current_status = self.get_status() - if self.current_status['current_stage'] in ('standby','awaiting_start'): + self.log.warning("resetting state...") + current_status = self.get_status() + if current_status['status'] in ('ready_to_start',): self.log.info("ready to start") + elif current_status['status'] in ('pressure_high', 'pressure_low', 'fault'): + self.log.info(f"{current_status['status']}, performing self check to reset") + elif current_status['status'] == "testing": + self.log.info("stop running test") + self.send_command("reset_test") else: - self.log.warning("not ready to start, performing self check to reset") - self.send_command("self_check") + self.log.error(f"unknown state {current_status['status']}") + time.sleep(2) def get_status(self): - status_str=str(self.send_enquiry("current_status"),encoding="ascii") - status_str+='z' # dummy terminator - status_vars=OrderedDict( - { - 'a':'counter', - 'b':'product_number', - 'c':'step_number', - 'd':'new_result_available', - 'e':'mode', - 'f':'status', - 'g':'pressure_reading', - 'i':'leak_reading', - 'k':'current_stage', - 'z':'dummy' - }) - status_decoded={} - for tag,param in status_vars.items(): - next_tag=list(status_vars)[list(status_vars.keys()).index(tag) + 1] - match=re.search(f"{tag}([0-9.-]+){next_tag}",status_str) - value=None + status_str = str(self.send_enquiry("current_status"), encoding="ascii") + status_str += 'z' # dummy terminator + status_vars = OrderedDict( + { + 'a': 'counter', + 'b': 'product_number', + 'c': 'step_number', + 'd': 'new_result_available', + 'e': 'mode', + 'f': 'status', + 'g': 'pressure_reading', + 'h': 'pressure_units', + 'i': 'leak_reading', + 'j': 'leak_offset', + 'k': 'current_stage', + 'z': 'dummy' + }) + status_decoded = {} + for tag, param in status_vars.items(): + next_tag = list(status_vars)[list(status_vars.keys()).index(tag) + 1] + match = re.search(f"{tag}([0-9.-]+){next_tag}", status_str) + value = None if match is not None: - value=match.group(1) + value = match.group(1) if param == 'status': value = self.enums['status_status'][value] - if param == 'current_stage': + elif param == 'current_stage': value = self.enums['status_current_stage'][value] + elif param == 'pressure_reading': + value = f"{float(value) * 1000:.1f}" - status_decoded[param]=value - if next_tag =='z': + status_decoded[param] = value + if next_tag == 'z': break return status_decoded + def get_last_result(self): + res_str = str(self.send_enquiry("last_test_result"), encoding="ascii") + res_str += 'z' # dummy terminator + status_vars = OrderedDict( + { + 'a': 'counter', + 'b': 'step_number', + 'c': 'product_number', + 'd': 'status', + 'z': 'dummy' + }) + res_decoded = {} + for tag, param in status_vars.items(): + next_tag = list(status_vars)[list(status_vars.keys()).index(tag) + 1] + match = re.search(f"{tag}([0-9.-]+){next_tag}", res_str) + value = None + if match is not None: + value = match.group(1) + if param == 'status': + value = self.enums['status_result'].get(value, 'NOK') + + res_decoded[param] = value + if next_tag == 'z': + break + + return res_decoded + def write_recipe(self, recipe, step, table=None): # PREPARE DATA - product_id='"'+recipe.part_number[:16]+'"' - product_id=product_id.encode("ascii") - test_press_bar=step.spec["test_pressure"]/1000 - prefill_press_bar=step.spec["pre_filling_pressure"]/1000 - tolerance=int(step.spec["settling_pressure_min_percent"]) - fail_pos=test_press_bar+(int(step.spec["test_pressure_qpos"])/1000) - fail_neg=test_press_bar+(int(step.spec["test_pressure_qneg"])/1000) - fill_time=float(step.spec["filling_time"]) - stab_time=float(step.spec["settling_time"]) - test_time=float(step.spec["test_time"]) - prefill_time=float(step.spec["pre_filling_time"]) - vent_time=float(step.spec["flush_time"]) + product_id = '"' + recipe.part_number[:16] + '"' + product_id = product_id.encode("ascii") + test_press_bar = step.spec["test_pressure"] / 1000 + prefill_press_bar = step.spec["pre_filling_pressure"] / 1000 + tolerance = int(step.spec["settling_pressure_min_percent"]) + fail_pos = test_press_bar + (int(step.spec["test_pressure_qpos"]) / 1000) + fail_neg = test_press_bar + (int(step.spec["test_pressure_qneg"]) / 1000) + fill_time = float(step.spec["filling_time"]) + stab_time = float(step.spec["settling_time"]) + test_time = float(step.spec["test_time"]) + prefill_time = float(step.spec["pre_filling_time"]) + vent_time = float(step.spec["flush_time"]) # SEND RECIPE PARAMETERS self.send_command("change_cur_prod_50") self.send_product_tag("product_id", product_id) @@ -175,57 +223,60 @@ class FurnessControlsLeakTester(Component): self.send_product_tag("fail_low", f"{fail_neg:3.1f}") self.send_product_tag("outputs_a_h", f"{int(0b01000000)}") + self.get_last_result() # CLEAR POSSIBLE NEW RESULT AVAILABLE FLAG - def send_command(self,command): + def send_command(self, command): if type(command) is str: - command=self.commands[command] - out_bytes= bytearray() + command = self.commands[command] + out_bytes = bytearray() out_bytes.extend(EOT) out_bytes.extend(self.id1) out_bytes.extend(self.id2) out_bytes.extend(command) out_bytes.extend(ETX) - checksum=self.calc_checksum(out_bytes) + checksum = self.calc_checksum(out_bytes) out_bytes.append(checksum) - + self.lock.lock() self.conn.write(out_bytes) - response = self.conn.read(100) + response = self.conn.read(1) + self.lock.unlock() if response == ACK: return True else: self.log.error(f"SEND COMMAND({command}):{response}") return None - def send_enquiry(self,enquiry): + def send_enquiry(self, enquiry): if type(enquiry) is str: - enquiry=self.commands[enquiry] - out_bytes=bytearray(EOT) + enquiry = self.commands[enquiry] + out_bytes = bytearray(EOT) out_bytes.extend(self.id1) out_bytes.extend(self.id2) out_bytes.extend(enquiry) out_bytes.extend(ENQ) checksum = self.calc_checksum(out_bytes) out_bytes.append(checksum) - + self.lock.lock() self.conn.write(out_bytes) response = self.conn.read(100) + self.lock.unlock() if len(response): read_checksum = response[-1] else: read_checksum = None - calculated_checksum = self.calc_checksum(response[0:-1],start_idx=0) + calculated_checksum = self.calc_checksum(response[0:-1], start_idx=0) if read_checksum != calculated_checksum: - self.log.error(f"SEND ENQUIRY:{response}") + self.log.error(f"ENQUIRY RESPONSE CHECKSUM:{read_checksum}!={calculated_checksum}") return None else: - response = response[:-2] #strip checksum & ETX + response = response[:-2] # strip checksum & ETX return response - def send_product_tag(self,tag,tag_data): + def send_product_tag(self, tag, tag_data): self.log.info(f"Sending tag:{tag}={tag_data}") - command=bytearray(self.commands["product_data"]) + command = bytearray(self.commands["product_data"]) if type(tag_data) is str: - tag_data=bytearray(tag_data,encoding="ascii") + tag_data = bytearray(tag_data, encoding="ascii") command.extend(self.product_tags[tag]) command.extend(tag_data) self.send_command(command) diff --git a/src/components/tecna_marposs_provaset_t3.py b/src/components/tecna_marposs_provaset_t3.py index 22be9d2..35d10ae 100644 --- a/src/components/tecna_marposs_provaset_t3.py +++ b/src/components/tecna_marposs_provaset_t3.py @@ -300,7 +300,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): "PSQ - Next sequence program PSOUT mode": 0, "RAMPS: T1 configuration": pid_ramps, "PID: pressure correction": 100, - "Various flags": 0b0000000000010000 if self.config["recipes_defaults"]["tecna_discharge_enable"]=="yes" else 0b0000000000000000 + "Various flags": 0b0000000000010000 if self.config["recipes_defaults"]["tester_discharge_enable"]=="yes" else 0b0000000000000000 } if self.model == "t3p": diff --git a/src/ui/about/about.ui b/src/ui/about/about.ui index 54b403b..4cec820 100644 --- a/src/ui/about/about.ui +++ b/src/ui/about/about.ui @@ -78,41 +78,27 @@ - - - Telefono: - - - - - - - +39 0118000876 - - - - P.IVA: - + 11836090016 - + Indirizzo: - + Via Vittime delle Foibe, 10 10036 - Settimo Torinese (TO) diff --git a/src/ui/imgs/r5.png b/src/ui/imgs/r5.png new file mode 100644 index 0000000000000000000000000000000000000000..84d2b0b0302e7c6f3ae94ffd2df276695e48c432 GIT binary patch literal 12091 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ƢU34Q0!-L188T?z}^{pdGJRi5$qJi>*SnCZoD{Qs!$xdQJw1qC+bc2nlnh&A*Nzrpaf-*sT`#U6Y$XRWHbB6u=i=0~b zoCX|hg~eAnEWMXbKqRqUY;sz zl0Xy1*Ym1#LI`b*1iL*~pxh|vqBoZCh$QhUFeF|csJ(TS*j>ebr-`a4Y7X898*hXT zQBXsfNG|Na=sT;j)@K-0eF=zd3)A-Mex&BmOzAla3Fm@E-iuXUy73l2ux%!J@Ndo-krZ{11tdJ^~ zWz=_nWg*E_B?T!*?A6F~vCYex@x?%oxF6=xd*`jaq{rM?-~een6zsj?F1YU(?|<*I z-et~|-7I)h4AqTfw%7+ld$7-tZFJFAm=!L<#D?&fC|#nE$epZNRkTXd39b^wdV(^; zFiDv8F_M_|Va97c^Z2HqfHW2;h9&@VpV!?aiyL8H0RoGx9#AOak>w7{uXb%~Xan`j zIIS1B1Y*v>x?i5o0t 20 + 75 true @@ -961,6 +962,7 @@ 20 + 75 true @@ -1437,6 +1439,7 @@ 20 + 75 true @@ -1468,6 +1471,7 @@ 12 + 75 true @@ -1487,6 +1491,7 @@ 12 + 75 true @@ -1534,6 +1539,7 @@ 12 + 75 true @@ -1552,6 +1558,7 @@ 20 + 50 false @@ -1570,6 +1577,7 @@ border: 1px solid black; 16 + 50 false @@ -1589,6 +1597,7 @@ border: 1px solid black; 20 + 50 false @@ -1613,6 +1622,7 @@ border: 1px solid black; 20 + 50 false @@ -1631,6 +1641,7 @@ border: 1px solid black; 16 + 50 false @@ -1644,6 +1655,7 @@ border: 1px solid black; 16 + 50 false @@ -1663,6 +1675,7 @@ border: 1px solid black; 20 + 50 false @@ -1703,6 +1716,7 @@ border: 1px solid black; 20 + 50 false @@ -1720,7 +1734,8 @@ border: 1px solid black; - 16 + 20 + 50 false @@ -1739,6 +1754,7 @@ border: 1px solid black; 16 + 50 false @@ -1752,6 +1768,7 @@ border: 1px solid black; 16 + 50 false @@ -1771,6 +1788,7 @@ border: 1px solid black; 16 + 50 false @@ -1806,6 +1824,7 @@ border: 1px solid black; 16 + 50 false @@ -1828,6 +1847,7 @@ border: 1px solid black; 20 + 50 false @@ -1864,6 +1884,7 @@ border: 1px solid black; 48 + 50 false @@ -1885,6 +1906,7 @@ border: 1px solid black; 16 + 50 false @@ -1901,6 +1923,7 @@ border: 1px solid black; 16 + 50 false @@ -1917,6 +1940,7 @@ border: 1px solid black; 16 + 50 false @@ -1930,6 +1954,7 @@ border: 1px solid black; 16 + 50 false @@ -1946,6 +1971,7 @@ border: 1px solid black; 16 + 50 false @@ -1962,6 +1988,7 @@ border: 1px solid black; 16 + 50 false @@ -1975,6 +2002,7 @@ border: 1px solid black; 16 + 50 false @@ -1991,6 +2019,7 @@ border: 1px solid black; 16 + 50 false @@ -2013,6 +2042,7 @@ border: 1px solid black; 20 + 50 false @@ -2031,6 +2061,7 @@ border: 1px solid black; 16 + 50 false @@ -2044,6 +2075,7 @@ border: 1px solid black; 16 + 50 false @@ -2066,6 +2098,7 @@ border: 1px solid black; 20 + 50 false @@ -2090,6 +2123,7 @@ border: 1px solid black; 20 + 50 false @@ -2108,6 +2142,7 @@ border: 1px solid black; 16 + 50 false @@ -2121,6 +2156,7 @@ border: 1px solid black; 16 + 50 false @@ -2133,7 +2169,8 @@ border: 1px solid black; - 16 + 20 + 50 false @@ -2151,7 +2188,8 @@ border: 1px solid black; - 16 + 20 + 50 false @@ -2170,6 +2208,7 @@ border: 1px solid black; 16 + 50 false @@ -2186,6 +2225,7 @@ border: 1px solid black; 16 + 50 false @@ -2202,6 +2242,7 @@ border: 1px solid black; 16 + 50 false