This commit is contained in:
matteo porta 2022-09-14 16:53:55 +02:00
parent b44005ed05
commit daa7edbb0a
7 changed files with 155 additions and 84 deletions

Binary file not shown.

View File

@ -7,7 +7,7 @@
^LL1071 ^LL1071
^LS0 ^LS0
^FT32,94^A0N,23,24^FH\^FDNumero Disegno^FS ^FT32,94^A0N,23,24^FH\^FDNumero Disegno^FS
^FT39,240^A0N,20,19^FH\^FD{DATAMATRIX_TEXT}^FS ^FT39,240^A0N,20,19^FH\^FD{PART}{MO}{YY}{SN5}^FS
^FT39,291^A0N,20,19^FH\^FDN. Pezzo:^FS ^FT39,291^A0N,20,19^FH\^FDN. Pezzo:^FS
^FT36,318^A0N,20,19^FH\^FD{DATETIME}^FS ^FT36,318^A0N,20,19^FH\^FD{DATETIME}^FS
^FT42,359^A0N,20,19^FH\^FDTurno:^FS ^FT42,359^A0N,20,19^FH\^FDTurno:^FS
@ -22,20 +22,20 @@
^FT34,709^A0N,20,19^FH\^FDCaduta Tollerata^FS ^FT34,709^A0N,20,19^FH\^FDCaduta Tollerata^FS
^FT34,736^A0N,20,19^FH\^FDmax (Bar)^FS ^FT34,736^A0N,20,19^FH\^FDmax (Bar)^FS
^FT34,763^A0N,20,19^FH\^FDPress Min Prova (Bar)^FS ^FT34,763^A0N,20,19^FH\^FDPress Min Prova (Bar)^FS
^FT136,291^A0N,20,19^FH\^FD{PIECE_NUM}^FS ^FT136,291^A0N,20,19^FH\^FD{SN}^FS
^FT145,359^A0N,20,19^FH\^FD{SHIFT}^FS ^FT145,359^A0N,20,19^FH\^FD{SHIFT}^FS
^FT138,413^A0N,20,19^FH\^FD{OPERATOR}^FS ^FT138,413^A0N,20,19^FH\^FD{OPERATOR}^FS
^FT184,520^A0N,20,19^FH\^FD{PMAX}^FS ^FT184,520^A0N,20,19^FH\^FD{PMAX}^FS
^FT184,547^A0N,20,19^FH\^FD{PMIN}^FS ^FT184,547^A0N,20,19^FH\^FD{PMIN}^FS
^FT185,574^A0N,20,19^FH\^FD{LEAK}^FS ^FT185,574^A0N,20,19^FH\^FD{RESLEAK}^FS
^FT257,628^A0N,20,19^FH\^FD{TFILL}^FS ^FT257,628^A0N,20,19^FH\^FD{TFILL}^FS
^FT257,655^A0N,20,19^FH\^FD{TSTAB}^FS ^FT257,655^A0N,20,19^FH\^FD{TSET}^FS
^FT257,682^A0N,20,19^FH\^FD{TTEST}^FS ^FT257,682^A0N,20,19^FH\^FD{TTEST}^FS
^FT257,736^A0N,20,19^FH\^FD{MAXLEAK}^FS ^FT257,736^A0N,20,19^FH\^FD{PMAX}^FS
^FT257,763^A0N,20,19^FH\^FD{PTESTMIN}^FS ^FT257,763^A0N,20,19^FH\^FD{PMIN}^FS
^FT138,386^A0N,20,19^FH\^FD{STATION}^FS ^FT138,386^A0N,20,19^FH\^FD{STATION}^FS
^BY80,80^FT42,196^BXN,5,200,0,0,1,~ ^BY80,80^FT42,196^BXN,5,200,0,0,1,~
^FH\^FD{DATAMATRIX}^FS ^FH\^FD{PART}{MO}{YY}{SN5}^FS
^FT56,906^A0N,36,36^FH\^FD{RESULT_L2}^FS ^FT56,906^A0N,36,36^FH\^FD{RESULT_L2}^FS
^FT56,868^A0N,36,36^FH\^FD{RESULT_L1}^FS ^FT56,868^A0N,36,36^FH\^FD{RESULT_L1}^FS
^FO32,454^GB292,0,8^FS ^FO32,454^GB292,0,8^FS

View File

@ -1,4 +1,4 @@
#!/bin/bash -e #!/bin/bash -e
cd "$(dirname "$0")" cd "$(dirname "$0")"
source "./venv/bin/activate" || source "./venv/Scripts/activate" || : source "./venv/bin/activate" || source "./venv/Scripts/activate" || :
python -O "./src/main.py" --no-edgetpu --no-tflite python -O "./src/main.py" --no-edgetpu --no-tflite $*

View File

@ -39,31 +39,49 @@ class Os_Label_Printer(Component):
# LABEL PRINT # LABEL PRINT
label = label.format(**context) label = label.format(**context)
if platform.system() == "Windows": if platform.system() == "Windows":
printer = win32print.OpenPrinter(self.printer) try:
job = win32print.StartDocPrinter(printer, 1, ("label", None, "RAW")) printer = win32print.OpenPrinter(self.printer)
win32print.WritePrinter(printer, bytes(label, encoding="utf8", errors="surrogateescape")) job = win32print.StartDocPrinter(printer, 1, ("label", None, "RAW"))
win32print.EndPagePrinter(printer) win32print.WritePrinter(printer, bytes(label, encoding="utf8", errors="surrogateescape"))
return True win32print.EndPagePrinter(printer)
return label
except Exception as e:
self.log.exception(traceback.format_exc())
QMessageBox.critical(
None,
"Errore Stampante",
f"Non e stato possibile stampare l'etichetta.\n\nErrore:\n{e}"
)
return None
else: else:
os.makedirs("tmp", exist_ok=True) try:
label_file = "tmp/label.prn" os.makedirs("tmp", exist_ok=True)
with open(label_file, "w", errors="surrogateescape") as f: label_file = "tmp/label.prn"
label = f.write(label) with open(label_file, "w", errors="surrogateescape") as f:
if self.platform == "windows": label = f.write(label)
cmd = f'print /d:"{self.printer}" "{label_file}"' if self.platform == "windows":
elif self.platform == "cups": cmd = f'print /d:"{self.printer}" "{label_file}"'
cmd = f'lp -d "{self.printer}" "{label_file}"' elif self.platform == "cups":
else: cmd = f'lp -d "{self.printer}" "{label_file}"'
raise NotImplementedError(f"platform {self.platform!r} is not supported") else:
if not self.simulate: raise NotImplementedError(f"platform {self.platform!r} is not supported")
p = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True) # unsafe if not self.simulate:
if p.returncode != 0: p = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True) # unsafe
self.log.exception(f"failed to print: returncode: {p.returncode}\noutput:\n{p.stdout}") if p.returncode != 0:
QMessageBox.critical( self.log.exception(f"failed to print: returncode: {p.returncode}\noutput:\n{p.stdout}")
None, QMessageBox.critical(
"Errore Stampante", None,
f"Non e stato possibile stampare l'etichetta.\n\nErrore:\nreturncode: {p.returncode}\noutput:\n{p.stdout}" "Errore Stampante",
) f"Non e stato possibile stampare l'etichetta.\n\nErrore:\nreturncode: {p.returncode}\noutput:\n{p.stdout}"
return False )
return True return None
return False return label
except Exception as e:
self.log.exception(traceback.format_exc())
QMessageBox.critical(
None,
"Errore Stampante",
f"Non e stato possibile stampare l'etichetta.\n\nErrore:\n{e}"
)
return None
return None

View File

@ -48,9 +48,18 @@ class Serial_Label_Printer(Component):
) )
conn.write(label.encode(errors="surrogateescape")) conn.write(label.encode(errors="surrogateescape"))
conn.close() conn.close()
return label
except serial.serialutil.SerialException as e: except serial.serialutil.SerialException as e:
QMessageBox.critical( QMessageBox.critical(
None, None,
"Errore Connessione Stampante", "Errore Connessione Stampante",
"Non e stato possibile connettersi alla stampante di etichette\nL'etichetta non verra stampata.\n\nErrore:\n" + str(e) "Non e stato possibile connettersi alla stampante di etichette\nL'etichetta non verra stampata.\n\nErrore:\n" + str(e)
) )
return None
except Exception as e:
QMessageBox.critical(
None,
"Errore Stampante",
f"Non e stato possibile stampare l'etichetta.\n\nErrore:\n{e}"
)
return None

View File

@ -1,6 +1,6 @@
from datetime import datetime from datetime import datetime
from peewee import AutoField, BooleanField, DateTimeField, ForeignKeyField from peewee import AutoField, BooleanField, DateTimeField, ForeignKeyField, TextField
from playhouse.sqlite_ext import JSONField from playhouse.sqlite_ext import JSONField
from .base_model import BaseModel, db from .base_model import BaseModel, db
@ -12,46 +12,47 @@ class Archive(BaseModel):
id = AutoField(primary_key=True, unique=True, null=False) id = AutoField(primary_key=True, unique=True, null=False)
time = DateTimeField(unique=True, null=False, default=datetime.now) time = DateTimeField(unique=True, null=False, default=datetime.now)
user = ForeignKeyField(Users, Users.username, null=False) user = ForeignKeyField(Users, Users.username, null=False)
recipe = ForeignKeyField(Recipes, null=False)
result = BooleanField(null=False) result = BooleanField(null=False)
overridden = BooleanField(null=False) overridden = BooleanField(null=False)
test_data = JSONField(null=False) test_data = JSONField(null=False)
label = TextField(null=True)
archived = BooleanField(null=False, default=False) archived = BooleanField(null=False, default=False)
uploaded = BooleanField(null=False, default=False) uploaded = BooleanField(null=False, default=False)
@classmethod @classmethod
@db.atomic() @db.atomic()
def archive(cls, recipe, test_data, result, overridden): def archive(cls, recipe, test_data, result, overridden):
parsed_test_data = { # parsed_test_data = {
"ESITO GLOBALE COLLAUDO": "OK" if test_data.get("ok", None) else "KO", # "ESITO GLOBALE COLLAUDO": "OK" if test_data.get("ok", None) else "KO",
} # "recipe": test_data.get("recipe", None),
total_duration = 0 # }
for step_name in [ # total_duration = 0
"autotest", # for step_name in [
"barcodes", # "autotest",
"connector", # "barcodes",
"leak", # "connector",
"print", # "leak",
"resistance", # "print",
"vision", # "resistance",
]: # "vision",
for k, v in test_data.get(step_name, {}).items(): # ]:
if step_name not in parsed_test_data: # for k, v in test_data.get(step_name, {}).items():
parsed_test_data[step_name] = {} # if step_name not in parsed_test_data:
parsed_test_data[step_name][k] = { # parsed_test_data[step_name] = {}
f"ESITO {step_name}": "OK" if v.get("ok", None) else "KO", # parsed_test_data[step_name][k] = {
"result": v.get("results", {}).get("result", None), # f"ESITO {step_name}": "OK" if v.get("ok", None) else "KO",
"data": v.get("results", {}).get("data", None), # "result": v.get("results", {}).get("result", None),
"spec": v.get("step", {}).get("spec", None), # "data": v.get("results", {}).get("data", None),
"duration": v.get("duration", None), # "step": v.get("step", None),
} # "duration": v.get("duration", None),
if parsed_test_data[step_name][k]["duration"] is not None: # }
total_duration += parsed_test_data[step_name][k]["duration"] # if parsed_test_data[step_name][k]["duration"] is not None:
parsed_test_data["DURATA TOTALE COLLAUDO"] = total_duration # total_duration += parsed_test_data[step_name][k]["duration"]
# parsed_test_data["DURATA TOTALE COLLAUDO"] = total_duration
return cls.create( return cls.create(
user=Users.get_session().user, user=Users.get_session().user,
recipe=recipe, recipe=recipe,
test_data=parsed_test_data, test_data=test_data,
result=result, result=result,
overridden=overridden, overridden=overridden,
) )

View File

@ -213,6 +213,8 @@ class Test(Widget):
}) })
self.log.info(f"cycle next: next cycle step: {self.step!r}") self.log.info(f"cycle next: next cycle step: {self.step!r}")
# INIT TEST DATA IF STARTING CYCLE LOOP # INIT TEST DATA IF STARTING CYCLE LOOP
if self.recipe is not None and "recipe" not in self.data:
self.data["recipe"] = model_to_dict(self.recipe)
if self.cycle_index == 0: if self.cycle_index == 0:
self.data = {"ok": True, "overridden": False} self.data = {"ok": True, "overridden": False}
self.archived = None self.archived = None
@ -225,7 +227,9 @@ class Test(Widget):
self.archived = self.done() self.archived = self.done()
self.next_timer.start(2000) self.next_timer.start(2000)
elif self.step.type == "print": elif self.step.type == "print":
self.print(self.archived, self.step.spec.get("template", "EtichettaR5")) compiled_label = self.print(self.archived, self.step.spec.get("template", "EtichettaR5"))
self.archived.label = compiled_label
self.archived.save()
self.next_timer.start(2000) self.next_timer.start(2000)
elif self.step.type == "fail": elif self.step.type == "fail":
self.next_timer.start(2000) self.next_timer.start(2000)
@ -324,35 +328,74 @@ class Test(Widget):
self.pieces[0] += 1 self.pieces[0] += 1
return archived return archived
@staticmethod
def labellify(v):
if not isinstance(v, str):
v = f"{v:.3f}"
return v
def print(self, archived, label): def print(self, archived, label):
self.log.info("cycle print") self.log.info("cycle print")
if archived.label is not None:
raise AssertionErrror("this should never happen")
self.components["label_printer"].print_label(archived.label, context=None)
self.log.info("cycle printed already compiled label")
# LABEL PRINT # LABEL PRINT
leak_test_1 = self.data.get("leak", {}).get(0, {}) recipe = archived.test_data.get("recipe", {})
leak_test_1_step_spec = leak_test_1.get("step", {}).get("spec", {}) leak_test_1 = archived.test_data.get("leak", {}).get(0, {})
leak_test_1_step = leak_test_1.get("step", {})
leak_test_1_step_spec = leak_test_1_step.get("spec", {})
leak_test_1_results = leak_test_1.get("results", {}) leak_test_1_results = leak_test_1.get("results", {})
leak_test_1_results_data = leak_test_1_results.get("data", {}) leak_test_1_results_data = leak_test_1_results.get("data", {})
datamatrix = str(archived.recipe.part_number) + archived.time.strftime("%m%y") + f"{archived.id:0>5}"
pmax = leak_test_1_step_spec.get("test_pressure", "-")
pmin = leak_test_1_results_data.get("Running test: pressure at the end of settling", "-")
leak = leak_test_1_results_data.get("Running test: measured leak", "-")
context = { context = {
"DATAMATRIX": datamatrix, # RECIPE DATA
"DATAMATRIX_TEXT": datamatrix, "RECIPE": self.labellify(recipe.get("name", "-")),
"PIECE_NUM": str(archived.id), "CLIENT": self.labellify(recipe.get("client", "-")),
"PART": self.labellify(recipe.get("part_number", "-")),
# STEP SPEC
"TPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_time", "-")),
"PPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_pressure", "-")),
"TFILL": self.labellify(leak_test_1_step_spec.get("filling_time", "-")),
"TSET": self.labellify(leak_test_1_step_spec.get("settling_time", "-")),
"PSETMINP": self.labellify(leak_test_1_step_spec.get("settling_pressure_min_percent", " -")),
"PSETMAXP": self.labellify(leak_test_1_step_spec.get("settling_pressure_max_percent", " -")),
"TTEST": self.labellify(leak_test_1_step_spec.get("test_time", "-")),
"PMIN": self.labellify(leak_test_1_step_spec.get("test_pressure_min_delta", "-")),
"PTEST": self.labellify(leak_test_1_step_spec.get("test_pressure", "-")),
"PMAX": self.labellify(leak_test_1_step_spec.get("test_pressure_max_delta", "-")),
"TFLUSH": self.labellify(leak_test_1_step_spec.get("flush_time", "-")),
"PFLUSH": self.labellify(leak_test_1_step_spec.get("flush_pressure", "-")),
# ACTUAL TESTED VALUES
"RESTPB": self.labellify(leak_test_1_results_data.get("Running test: phase backwards time", "-")),
"RESPFILL": self.labellify(leak_test_1_results_data.get("Running test: filling pressure", "-")),
"RESPSET": self.labellify(leak_test_1_results_data.get("Running test: pressure at the end of settling", "-")),
"RESPB": self.labellify(leak_test_1_results_data.get("Running test: burst pressure", "-")),
"RESLEAK": self.labellify(leak_test_1_results_data.get("Running test: measured leak", "-")),
"RESFLOW": self.labellify(leak_test_1_results_data.get("Running test: calculated leak flow rate", "-")),
"RESRVP": self.labellify(leak_test_1_results_data.get("Running test: calculate RVP%", "-")),
"RESRES": self.labellify(leak_test_1_results_data.get("Running test: result", "-")),
# SERIAL DEFINITION
"SN": str(archived.id),
"SN5": f"{archived.id:0>5}",
"SN6": f"{archived.id:0>6}",
# TIME DEFINITION
"DATETIME": archived.time.strftime("%d/%m/%Y %H:%M:%S"), "DATETIME": archived.time.strftime("%d/%m/%Y %H:%M:%S"),
"YYYY": archived.time.strftime("%Y"),
"YY": archived.time.strftime("%y"),
"MO": archived.time.strftime("%m"),
"DD": archived.time.strftime("%d"),
"HH": archived.time.strftime("%H"),
"MI": archived.time.strftime("%M"),
"SS": archived.time.strftime("%S"),
# EXTRA DATA
"SHIFT": str(get_shift(archived.time)), "SHIFT": str(get_shift(archived.time)),
"STATION": str(self.machine_id), "STATION": str(self.machine_id),
"OPERATOR": str(Users.get_session().user.username), "OPERATOR": str(archived.user.username),
"PMAX": f"{pmax:.3f}" if type(pmax) is not str else pmax, # RESULT
"PMIN": f"{pmin:.3f}" if type(pmin) is not str else pmin, "RESULT": str("CONFORME" if leak_test_1_results.get("ok", False) else "SCARTO") + str(" FORZATO" if self.data.get("overridden", False) else ""),
"LEAK": f"{leak:.3f}" if type(leak) is not str else leak,
"TFILL": str(leak_test_1_step_spec.get("filling_time", "-")),
"TSTAB": str(leak_test_1_step_spec.get("settling_time", "-")),
"TTEST": str(leak_test_1_step_spec.get("test_time", "-")),
"MAXLEAK": str(leak_test_1_step_spec.get("test_pressure_max_delta", "-")),
"PTESTMIN": str(leak_test_1_step_spec.get("test_pressure_min_delta", "-")),
"RESULT_L1": "ESITO" + str(" FORZATO" if self.data.get("overridden", False) else ""), "RESULT_L1": "ESITO" + str(" FORZATO" if self.data.get("overridden", False) else ""),
"RESULT_L2": str("CONFORME" if leak_test_1_results.get("ok", False) else "SCARTO"), "RESULT_L2": str("CONFORME" if leak_test_1_results.get("ok", False) else "SCARTO"),
} }
self.components["label_printer"].print_label(label, context=context) compiled_label = self.components["label_printer"].print_label(label, context=context)
self.log.info(f"cycle printed: {context!r}") self.log.info(f"cycle printed: {context!r}")
return compiled_label