2022-06-01 16:37:19 +00:00
import logging
import os
import sys
2022-08-23 14:00:04 +00:00
import weakref
2022-06-01 16:37:19 +00:00
from datetime import datetime
2022-07-19 09:59:00 +00:00
from lib . db import Archive , Steps , Users
2022-07-26 14:18:44 +00:00
from lib . helpers import get_shift
from playhouse . shortcuts import model_to_dict
2022-06-28 10:31:27 +00:00
from PyQt5 . QtCore import QTimer
2022-09-06 10:06:43 +00:00
from PyQt5 . QtWidgets import QMessageBox
2022-06-01 16:37:19 +00:00
from ui . helpers import replace_widget
from ui . recipe_selection import Recipe_Selection
from ui . test_assembly import Test_Assembly
2022-07-25 13:36:42 +00:00
from ui . test_barcodes import Test_Barcodes
2022-08-24 10:59:16 +00:00
from ui . test_connector import Test_Connector
2022-10-18 09:57:08 +00:00
from ui . test_count import Test_Count
from ui . test_count_end import Test_Count_End
2023-01-05 11:16:04 +00:00
from ui . test_warning_img import Test_Warning_Img
2022-09-20 15:42:59 +00:00
from ui . test_fail import Test_Fail
2022-07-12 08:48:04 +00:00
from ui . test_leak import Test_Leak
2022-08-23 14:00:04 +00:00
from ui . test_resistance import Test_Resistance
2022-10-04 11:51:36 +00:00
from ui . test_screws import Test_Screws
2022-06-22 15:18:29 +00:00
from ui . test_vision import Test_Vision
2022-06-01 16:37:19 +00:00
from ui . widget import Widget
class Test ( Widget ) :
2022-09-20 15:42:59 +00:00
def __init__ ( self , config , components = None ) :
2022-06-01 16:37:19 +00:00
super ( ) . __init__ ( )
2022-09-20 15:42:59 +00:00
self . config = config
2022-06-22 15:18:29 +00:00
self . components = components
2022-06-01 16:37:19 +00:00
# GET LOGGER
self . log = logging . getLogger ( " Test " )
2022-10-12 14:23:34 +00:00
# SHOW MACHINE DESCRIPTION
self . machine_description_l . setText ( self . config . get ( " machine " , { } ) . get ( " description " , " N/A " ) )
2022-06-01 16:37:19 +00:00
# SHOW USERNAME
2023-01-06 14:42:52 +00:00
class session ( ) :
is_admin = True
self . user_l . setText ( " user " )
2022-06-01 16:37:19 +00:00
if session . is_admin :
self . user_l . setStyleSheet ( " QLabel { color: red; } " )
else :
self . user_l . setStyleSheet ( " " )
# SHOW AND UPDATE TIME CLOCK
self . refresh_time ( init = True )
# INIT RECIPE
self . recipe = None
2022-07-19 09:59:00 +00:00
self . step = None
2022-09-06 10:06:43 +00:00
self . unsupported_steps = set ( )
self . steps_dependencies = {
2022-10-18 09:57:08 +00:00
" count " : set ( ) ,
2022-09-23 17:07:36 +00:00
" connector " : { " multicomp " , } ,
2022-10-18 09:57:08 +00:00
" screws " : { " screwdriver " , " tecna_t3 " , } ,
2022-09-06 10:06:43 +00:00
" resistance " : { " multicomp " , } ,
2022-10-18 09:57:08 +00:00
" leak " : { " tecna_t3 " , } ,
2022-10-11 13:30:53 +00:00
" vision " : { ( " uvc_camera " , " galaxy_camera " , ) , " vision " , " vision_saver " , } , # "neo_pixels", },
2022-10-18 09:57:08 +00:00
" print " : { " label_printer " , } ,
2022-09-06 10:06:43 +00:00
}
self . unsupported_steps = set ( )
for step_name , dependencies in self . steps_dependencies . items ( ) :
for dependency in dependencies :
2022-10-11 13:30:53 +00:00
if isinstance ( dependency , tuple ) :
2022-11-09 16:18:11 +00:00
# if all([d not in self.components or not self.components[d].ready for d in dependency]):
if all ( [ d not in self . components for d in dependency ] ) :
2022-10-11 13:30:53 +00:00
self . unsupported_steps . add ( step_name )
else :
2022-11-09 16:18:11 +00:00
# if dependency not in self.components or not self.components[dependency].ready:
if dependency not in self . components :
2022-10-11 13:30:53 +00:00
self . unsupported_steps . add ( step_name )
2022-10-18 09:57:08 +00:00
# INIT PIECES COUNTER
self . pieces = { " ok " : 0 , " ko " : 0 }
2022-06-01 16:37:19 +00:00
# INIT CYCLE STATES
2022-07-19 09:59:00 +00:00
self . cycle_available_steps = {
2022-08-02 16:15:30 +00:00
# "assembly_1": Test_Assembly(img_path=self.select_step_img("assembly_1"), text=u"INSERIRE SENSORE", widget=None),
" barcodes " : Test_Assembly ( img_path = self . select_step_img ( " scan " ) , text = u " LEGGERE IL BARCODE DEL PEZZO DA COLLAUDARE " , widget = Test_Barcodes ( ) ) ,
2022-08-24 10:59:16 +00:00
" connector " : Test_Assembly ( img_path = self . select_step_img ( " scan " ) , text = u " COLLEGARE IL CONNETTORE INDICATO AL PEZZO E LEGGERE IL SUO BARCODE " , widget = Test_Connector ( run_once = True ) ) ,
2022-10-18 09:57:08 +00:00
" count " : Test_Assembly ( img_path = None , text = u " INSERIRE IL NUMERO DI PEZZI ATTESI PER IL LOTTO " , widget = Test_Count ( components = self . components , recipe = self . recipe , step = self . step , pieces = self . pieces , run_once = True ) ) ,
2023-01-05 17:57:44 +00:00
" warning_img " : Test_Assembly ( img_path = None , text = u " ATTENZIONE - PER QUESTO CODICE ESEGUIRE LE OPERAZIONI INDICATE IN FIGURA " , widget = Test_Warning_Img ( components = self . components , recipe = self . recipe , step = self . step , run_once = True ) ) ,
2022-10-18 09:57:08 +00:00
" count_end " : Test_Assembly ( img_path = None , text = u " LOTTO TERMINATO, PREMERE CONTINUA PERCOMINCIARNE UNO NUOVO " , widget = Test_Count_End ( components = self . components , recipe = self . recipe , step = self . step , pieces = self . pieces ) ) ,
2022-08-02 16:15:30 +00:00
" done " : Test_Assembly ( img_path = self . select_step_img ( " success " ) , text = u " COLLAUDO COMPLETATO " , widget = None ) ,
" emergency " : Test_Assembly ( img_path = self . select_step_img ( " reset_emergency " ) , text = u " EMERGENZA INTERVENUTA - RIPRISTINARE PULSANTE E SELEZIONARE \" RESET EMERGENZA \" DAL MEN \u00d9 \" STRUMENTI \" " , widget = None ) ,
2022-09-20 15:42:59 +00:00
" fail " : Test_Assembly ( img_path = self . select_step_img ( " fail " ) , text = u " CICLO INTERROTTO, PREMERE CONTINUA PER COMINCIARE UN NUOVO CICLO " , widget = Test_Fail ( ) ) ,
2022-10-18 09:57:08 +00:00
" leak " : Test_Assembly ( img_path = None , text = None , widget = Test_Leak ( components = self . components , recipe = self . recipe , step = self . step , pieces = self . pieces ) ) ,
2022-08-02 16:15:30 +00:00
" print " : Test_Assembly ( img_path = self . select_step_img ( " print " ) , text = u " STAMPA ETICHETTA IN CORSO " , widget = None ) ,
2022-10-18 09:57:08 +00:00
" resistance " : Test_Assembly ( img_path = None , text = u " COLLEGARE CONNETTORE ELETTRICO PER EFFETTUARE PROVA RESISTENZA " , widget = Test_Resistance ( components = self . components , recipe = self . recipe , step = self . step , pieces = self . pieces ) ) ,
" screws " : Test_Assembly ( img_path = None , text = u " AVVITARE TUTE LE VITI COME INDICATO " , widget = Test_Screws ( components = self . components , recipe = self . recipe , step = self . step , pieces = self . pieces ) ) ,
2022-09-21 14:15:04 +00:00
" select_recipe " : Test_Assembly ( img_path = None , text = u " SELEZIONARE IL CODICE DA COLLAUDARE " , widget = Recipe_Selection ( config = self . config , unsupported_steps = self . unsupported_steps ) ) ,
2022-10-18 09:57:08 +00:00
" vision " : Test_Assembly ( img_path = None , text = u " VERIFICARE CONTROLLO CON TELECAMERA " , widget = Test_Vision ( components = self . components , recipe = self . recipe , step = self . step , pieces = self . pieces ) ) ,
2022-08-02 16:15:30 +00:00
" wait " : Test_Assembly ( img_path = self . select_step_img ( " wait " ) , text = u " ATTENDERE - PAUSA INTER CICLO " , widget = None ) ,
None : Test_Assembly ( img_path = self . select_step_img ( " warning " ) , text = u " ATTENZIONE - LA RICETTA SELEZIONATA NON CONTIENE FASI DI TEST " , widget = None ) ,
2022-06-01 16:37:19 +00:00
}
2022-07-19 09:59:00 +00:00
self . cycle_steps = None
2022-06-28 10:31:27 +00:00
self . cycle_index = - 1
2022-06-01 16:37:19 +00:00
# SETUP AUTOTEST
self . autotest_request = False
2022-11-15 16:17:59 +00:00
self . autotesting = False
self . autotesting_reason = None
self . autotest_cycle_steps = None
if " --no-autotest " not in sys . argv :
self . autotest_period = 12 * 60 * 60 * 1000
2023-01-03 16:57:14 +00:00
if not self . config [ " autotest_done " ] :
self . request_autotest ( " init " )
2022-11-15 16:17:59 +00:00
else :
self . autotest_period = None
2022-06-28 10:31:27 +00:00
# INIT TEST DATA
2022-07-26 10:24:53 +00:00
self . data = { " ok " : True , " overridden " : False }
self . archived = None
2022-06-01 16:37:19 +00:00
# CONNECT CYCLE CONTROLS
self . cancel_b . clicked . connect ( self . fail_cycle )
self . change_recipe_b . clicked . connect ( self . change_recipe )
2022-08-23 14:00:04 +00:00
for step_name , w in self . cycle_available_steps . items ( ) :
2022-06-01 16:37:19 +00:00
if hasattr ( w , " ok " ) :
# custom ok handlers should call next again
2022-08-23 14:00:04 +00:00
if isinstance ( w . widget , ( Recipe_Selection ) ) :
2022-06-01 16:37:19 +00:00
w . ok . connect ( self . set_recipe )
else :
2022-08-24 10:59:16 +00:00
w . ok . connect ( lambda data = None , step_name = step_name , self = weakref . ref ( self ) : self ( ) . set_step ( step_name , data ) )
2022-07-12 08:48:04 +00:00
if hasattr ( w , " ko " ) :
w . ko . connect ( self . fail_cycle )
2022-10-18 09:57:08 +00:00
# CUSTOM STEP CONNECTIONS
self . cycle_available_steps [ " count " ] . ok . connect ( self . cycle_available_steps [ " count_end " ] . widget . set_amount )
2023-01-05 17:57:44 +00:00
#self.cycle_available_steps["warning_img"].ok.connect(self.cycle_available_steps["warning_img"].widget.set_done)
2022-06-01 16:37:19 +00:00
# TESTING
if " --test " in sys . argv :
self . testing = True
else :
self . testing = False
# /TESTING
# START CYCLE
2022-07-12 08:48:04 +00:00
self . next_timer = QTimer ( )
self . next_timer . setSingleShot ( True )
self . next_timer . timeout . connect ( self . next )
2022-06-01 16:37:19 +00:00
self . next ( )
def refresh_time ( self , init = False ) :
if init :
self . time_timer = QTimer ( )
self . time_timer . setSingleShot ( True )
self . time_timer . timeout . connect ( self . refresh_time )
t = datetime . now ( )
self . time_l . setText ( " {d} / {mo} / {y} \n {h} : {m} " . format ( y = t . year , mo = t . month , d = t . day , h = t . hour , m = t . minute ) )
self . time_timer . start ( 60 - t . second )
def select_step_img ( self , step , suffix = None ) :
img_path = " ./src/ui/imgs "
names = [ ]
if suffix is not None :
2022-09-20 15:42:59 +00:00
names . append ( f " { step } _ { suffix } _ { self . config . machine_id } " )
2022-06-01 16:37:19 +00:00
names . append ( f " { step } _ { suffix } " )
2022-09-20 15:42:59 +00:00
names . append ( f " { step } _ { self . config . machine_id } " )
2022-06-01 16:37:19 +00:00
names . append ( f " { step } " )
for name in names :
for ext in [ " png " , " jpg " ] :
path = f " { img_path } / { name } . { ext } "
if os . path . isfile ( path ) :
return path
raise FileNotFoundError ( f " No image was found for step { step } " )
def change_recipe ( self ) :
self . next ( action = " change_recipe " )
def fail_cycle ( self ) :
self . next ( action = " fail " )
def setCentralWidget ( self , widget ) :
replace_widget ( self , " centralWidget " , widget )
def request_autotest ( self , reason ) : # you can cancel the request calling request_autotest(False)
self . log . info ( f " cycle request autotest: reason: { reason !r} autotest_request: { self . autotest_request !r} " )
if reason == " init " :
self . autotest_timer = QTimer ( )
self . autotest_timer . setSingleShot ( False )
self . autotest_timer . timeout . connect ( self . request_periodic_autotest )
self . time_timer . start ( self . autotest_period )
reason = " boot "
self . autotest_request = reason
def request_periodic_autotest ( self ) :
self . request_autotest ( " periodic " )
def next ( self , action = None ) :
2022-10-18 09:57:08 +00:00
if self . step is not None :
self . log . debug ( f " cycle next: cycle step: { model_to_dict ( self . step ) !r} action: { action !r} " )
else :
self . log . debug ( f " cycle next: cycle step: { self . step !r} action: { action !r} " )
2022-07-25 09:16:14 +00:00
current_w = self . centralWidget
if hasattr ( current_w , " stop " ) :
current_w . stop ( )
2022-06-01 16:37:19 +00:00
if action == " change_recipe " :
self . log . info ( f " cycle next: action: { action !r} " )
self . set_recipe ( recipe = None )
2022-07-19 09:59:00 +00:00
self . step = Steps ( type = " select_recipe " )
2022-06-28 10:31:27 +00:00
self . cycle_index = - 1
2022-08-02 16:15:30 +00:00
# COUNT RESET
2022-10-18 09:57:08 +00:00
self . pieces [ " ok " ] = 0
self . pieces [ " ko " ] = 0
2022-06-01 16:37:19 +00:00
elif action == " fail " :
self . log . info ( f " cycle next: action: { action !r} " )
# FAIL AND RESTART TEST
2022-07-19 09:59:00 +00:00
self . step = Steps ( type = " fail " )
2022-06-28 10:31:27 +00:00
self . cycle_index = - 1
2022-08-02 16:15:30 +00:00
# COUNT FAIL
2022-11-09 16:18:11 +00:00
self . done ( ok = False )
2022-06-01 16:37:19 +00:00
elif action is not None :
raise NotImplementedError ( f " cycle next: action { action !r} is not a valid action " )
2022-07-19 09:59:00 +00:00
# if action did not set the next cycle step
# set next cycle step normally
if self . recipe is None or self . cycle_steps is None :
2022-07-12 08:48:04 +00:00
# if recipe not set: select_recipe
2022-07-19 09:59:00 +00:00
self . step = Steps ( type = " select_recipe " )
elif action is None :
2022-11-15 16:17:59 +00:00
if self . autotest_request is not False and self . autotest_cycle_steps is not None and not self . autotesting and ( self . cycle_index == - 1 or self . cycle_index + 1 > = len ( self . cycle_steps ) ) :
# if autotest was requested
# and if cycle_steps is not started or has ended
self . autotesting = True
self . autotesting_reason = self . autotest_request
2022-07-12 08:48:04 +00:00
self . autotest_request = False
if self . autotest_period is not None : # reset periodic autotest timer
self . time_timer . start ( self . autotest_period )
2022-11-15 16:17:59 +00:00
if self . autotesting :
if self . cycle_index + 1 < len ( self . autotest_cycle_steps ) :
# goto next step in autotest_cycle_steps
self . cycle_index = ( self . cycle_index + 1 ) % len ( self . autotest_cycle_steps )
self . step = self . autotest_cycle_steps [ self . cycle_index ]
else :
# autotest ended
self . autotesting = False
self . autotesting_reason = None
self . cycle_index = - 1
2023-01-03 16:57:14 +00:00
self . config [ " autotest_done " ] = True
2022-11-15 16:17:59 +00:00
if not self . autotesting :
if len ( self . cycle_steps ) :
# goto next step in cycle_steps
self . cycle_index = ( self . cycle_index + 1 ) % len ( self . cycle_steps )
self . step = self . cycle_steps [ self . cycle_index ]
else :
self . cycle_index = - 1
self . step = Steps ( type = None )
2022-06-01 16:37:19 +00:00
# enable/disable cycle controls
self . change_recipe_b . setEnabled ( self . recipe is not None )
2022-07-19 09:59:00 +00:00
self . cancel_b . setEnabled ( self . step . type is not None and self . step . type not in {
2022-06-01 16:37:19 +00:00
" emergency " ,
" fail " ,
" select_recipe " ,
" wait " ,
} )
2022-10-18 09:57:08 +00:00
self . log . info ( f " cycle next: next cycle step: { model_to_dict ( self . step ) !r} " )
2022-10-25 13:38:18 +00:00
# INIT TEST DATA IF STARTING CYCLE LOOP OR IF RESET IS NEEDED
2022-11-15 16:17:59 +00:00
if self . cycle_index == 0 :
2022-07-26 10:24:53 +00:00
self . data = { " ok " : True , " overridden " : False }
self . archived = None
2022-10-25 13:38:18 +00:00
if self . recipe is not None and " recipe " not in self . data :
self . data [ " recipe " ] = model_to_dict ( self . recipe )
2022-07-19 09:59:00 +00:00
w = self . cycle_available_steps [ self . step . type ]
2022-10-18 09:57:08 +00:00
show = None
2022-08-24 10:59:16 +00:00
if hasattr ( w , " start " ) :
2022-11-15 16:17:59 +00:00
show = w . start ( recipe = self . recipe , step = self . step , pieces = self . pieces )
2022-10-18 09:57:08 +00:00
if show is not False and w is not current_w :
self . setCentralWidget ( w )
2022-10-24 14:51:58 +00:00
elif show is False :
self . next_timer . start ( 0 )
2022-07-19 09:59:00 +00:00
if self . step . type == " done " :
2022-07-26 10:24:53 +00:00
self . archived = self . done ( )
self . next_timer . start ( 2000 )
elif self . step . type == " print " :
2022-09-14 14:53:55 +00:00
compiled_label = self . print ( self . archived , self . step . spec . get ( " template " , " EtichettaR5 " ) )
self . archived . label = compiled_label
self . archived . save ( )
2022-07-12 08:48:04 +00:00
self . next_timer . start ( 2000 )
2022-09-20 15:42:59 +00:00
# elif self.step.type == "fail":
# self.next_timer.start(2000)
2022-07-19 09:59:00 +00:00
elif self . step . type == " wait " :
2022-10-19 12:09:15 +00:00
self . next_timer . start ( 2000 )
2022-06-01 16:37:19 +00:00
# UPDATE PIECES DISPLAY
2022-10-18 09:57:08 +00:00
self . pieces_count_l . setText ( f " { self . pieces [ ' ok ' ] } OK / { self . pieces [ ' ko ' ] } NOK / { sum ( self . pieces . values ( ) ) } TOT " )
2022-06-01 16:37:19 +00:00
def set_recipe ( self , recipe = None ) :
self . recipe = recipe
2022-07-19 09:59:00 +00:00
if self . recipe is None :
self . cycle_steps = None
2022-11-15 16:17:59 +00:00
self . autotest_cycle_steps = None
2022-07-19 09:59:00 +00:00
else :
2022-07-26 10:24:53 +00:00
steps = self . recipe . get_steps ( )
2022-09-07 15:24:40 +00:00
skip = set ( )
2022-07-26 10:24:53 +00:00
print_found = False
2022-10-18 09:57:08 +00:00
count_found = False
2022-07-26 10:24:53 +00:00
for i , step in enumerate ( steps ) :
2022-09-07 15:24:40 +00:00
if i in skip :
continue
2022-10-18 09:57:08 +00:00
if step . type == " count " :
count_found = True
2023-01-05 11:16:04 +00:00
if step . spec [ " warning_img " ] :
steps . insert ( i , Steps ( type = " warning_img " , spec = { " warning_img " : step . spec [ " warning_img " ] } ) )
skip . add ( i + 1 )
2022-09-07 15:24:40 +00:00
if step . type == " resistance " :
steps . insert ( i + 1 , Steps ( type = " resistance " , spec = {
" scale " : 500 ,
" expected " : float ( " +inf " ) ,
2022-11-15 16:53:15 +00:00
" tolerance_pos " : 0 ,
" tolerance_neg " : 0 ,
2022-09-07 15:24:40 +00:00
} ) )
skip . add ( i + 1 )
2022-07-26 10:24:53 +00:00
if step . type == " print " :
steps . insert ( i , Steps ( type = " done " ) )
print_found = True
2022-09-07 15:24:40 +00:00
skip . add ( i + 1 )
2022-10-18 09:57:08 +00:00
if count_found :
steps . insert ( i + 2 , Steps ( type = " count_end " ) )
2022-07-26 10:24:53 +00:00
if not print_found :
steps . append ( Steps ( type = " done " ) )
2022-10-18 09:57:08 +00:00
if count_found :
steps . append ( Steps ( type = " count_end " ) )
2022-07-26 10:24:53 +00:00
steps . append ( Steps ( type = " wait " ) )
self . cycle_steps = steps
2022-09-06 10:06:43 +00:00
self . check_steps_dependencies ( self . cycle_steps )
2022-11-15 16:17:59 +00:00
self . autotest_cycle_steps = [
* ( [
Steps ( type = " resistance " , spec = {
" scale " : 500 ,
2023-01-05 13:15:48 +00:00
" expected " : 1 ,
2022-11-15 16:53:15 +00:00
" tolerance_pos " : 5 ,
" tolerance_neg " : 5 ,
2022-11-15 16:17:59 +00:00
" autotest " : True ,
} ) ,
Steps ( type = " resistance " , spec = {
" scale " : 500 ,
" expected " : float ( " +inf " ) ,
2022-11-15 16:53:15 +00:00
" tolerance_pos " : 0 ,
" tolerance_neg " : 0 ,
2022-11-15 16:17:59 +00:00
" autotest " : True ,
} ) ,
Steps ( type = " resistance " , spec = {
" scale " : 500 ,
2023-01-05 13:15:48 +00:00
" expected " : 10 ,
" tolerance_pos " : 1 ,
" tolerance_neg " : 1 ,
2022-11-15 16:17:59 +00:00
" autotest " : True ,
} ) ,
Steps ( type = " resistance " , spec = {
" scale " : 500 ,
" expected " : float ( " +inf " ) ,
2022-11-15 16:53:15 +00:00
" tolerance_pos " : 0 ,
" tolerance_neg " : 0 ,
2022-11-15 16:17:59 +00:00
" autotest " : True ,
} ) ,
] if " resistance " not in self . unsupported_steps else [ ] ) ,
* ( [
Steps ( type = " leak " , spec = {
" pre_filling_time " : 0 ,
" pre_filling_pressure " : 1000 ,
2023-01-05 13:15:48 +00:00
" filling_time " : 5 ,
" settling_time " : 5 ,
2022-11-15 16:17:59 +00:00
" settling_pressure_min_percent " : 5 ,
" settling_pressure_max_percent " : 5 ,
" test_time " : 10 ,
2023-01-05 13:15:48 +00:00
" test_pressure_min_delta " : 5 ,
" test_pressure " : 9000 ,
" test_pressure_max_delta " : 5 ,
2022-11-15 16:17:59 +00:00
" flush_time " : 1 ,
" flush_pressure " : 100 ,
" autotest " : True ,
} ) ,
] if " leak " not in self . unsupported_steps else [ ] ) ,
2023-01-05 13:15:48 +00:00
* ( [
Steps ( type = " leak " , spec = {
" pre_filling_time " : 0 ,
" pre_filling_pressure " : 1000 ,
" filling_time " : 5 ,
" settling_time " : 5 ,
" settling_pressure_min_percent " : 5 ,
" settling_pressure_max_percent " : 5 ,
" test_time " : 10 ,
" test_pressure_min_delta " : 5 ,
" test_pressure " : 9000 ,
" test_pressure_max_delta " : 5 ,
" flush_time " : 1 ,
" flush_pressure " : 100 ,
" autotest " : False ,
} ) ,
] if " leak " not in self . unsupported_steps else [ ] ) ,
2022-11-15 16:17:59 +00:00
Steps ( type = " done " ) ,
Steps ( type = " wait " ) ,
]
2022-08-24 10:59:16 +00:00
for w in self . cycle_available_steps . values ( ) :
if hasattr ( w , " reset " ) :
w . reset ( )
2022-06-01 16:37:19 +00:00
# UPDATE RECIPE DISPLAY
if self . recipe is not None :
2022-10-18 09:57:08 +00:00
self . log . info ( f " cycle recipe: cycle recipe: { model_to_dict ( self . recipe ) !r} cycle steps: { [ model_to_dict ( s ) for s in self . cycle_steps ] } " )
2022-06-01 16:37:19 +00:00
self . recipe_l . setText ( self . recipe . name )
self . recipe_l . setStyleSheet ( " " )
self . next ( )
else :
2022-10-18 09:57:08 +00:00
self . log . info ( f " cycle recipe: cycle recipe: { self . recipe !r} cycle steps: { self . cycle_steps } " )
2022-06-01 16:37:19 +00:00
self . recipe_l . setText ( " NON SELEZIONATA " )
self . recipe_l . setStyleSheet ( " QLabel { color: red; } " )
2022-09-06 10:06:43 +00:00
def check_steps_dependencies ( self , steps ) :
unsupported_steps = set ( )
missing_components = set ( )
for step in steps :
if step . type in self . unsupported_steps or step . type not in self . cycle_available_steps :
unsupported_steps . add ( step . type )
else :
for dependency in self . steps_dependencies . get ( step . type , [ ] ) :
2022-10-11 13:30:53 +00:00
if isinstance ( dependency , tuple ) :
if all ( [ d not in self . components for d in dependency ] ) :
unsupported_steps . add ( step . type )
else :
2022-10-11 14:25:18 +00:00
unready = set ( )
2022-10-11 13:30:53 +00:00
for d in dependency :
2022-10-11 14:25:18 +00:00
if d in self . components :
2022-10-11 13:30:53 +00:00
if not self . components [ d ] . ready :
2022-10-11 14:25:18 +00:00
self . components [ d ] . reconfigure ( )
if not self . components [ d ] . ready :
unready . add ( d )
else :
unready . add ( d )
if unready == set ( dependency ) :
2022-10-11 13:30:53 +00:00
missing_components . add ( " or " . join ( dependency ) )
2022-09-06 10:06:43 +00:00
else :
2022-10-11 13:30:53 +00:00
if dependency not in self . components :
unsupported_steps . add ( step . type )
else :
2022-09-06 10:06:43 +00:00
if not self . components [ dependency ] . ready :
2022-10-11 13:30:53 +00:00
self . components [ dependency ] . reconfigure ( )
if not self . components [ dependency ] . ready :
missing_components . add ( dependency )
2022-09-06 10:06:43 +00:00
if len ( unsupported_steps ) :
QMessageBox . critical ( None , " Errore Ricetta " , f " Questa ricetta contiene uno o piu step non supportati da questo banco: \n { ' , ' . join ( sorted ( unsupported_steps ) ) } \n Modificare la ricetta adeguatamente. " )
if len ( missing_components ) :
QMessageBox . critical ( None , " Errore Componenti Ricetta " , f " Questa ricetta richiede i seguenti componenti per essere eseguita: \n { ' , ' . join ( sorted ( missing_components ) ) } \n Modificare la ricetta adeguatamente o collegare i componenti elencati. " )
if len ( unsupported_steps ) or len ( missing_components ) :
self . change_recipe ( )
2022-08-23 14:00:04 +00:00
def set_step ( self , step_name , data = None ) :
if step_name not in self . data :
self . data [ step_name ] = { }
2022-08-24 10:59:16 +00:00
if data is not None :
data [ " step " ] = model_to_dict ( self . step )
2022-10-03 11:48:59 +00:00
self . data [ step_name ] [ str ( len ( self . data [ step_name ] ) ) ] = data
2022-08-24 10:59:16 +00:00
self . data [ " overridden " ] = self . data [ " overridden " ] or data . get ( " overridden " , False )
self . data [ " ok " ] = self . data [ " ok " ] and data . get ( " ok " , False )
2022-07-12 08:48:04 +00:00
self . next ( )
2022-07-19 09:59:00 +00:00
def done ( self , ok = True ) :
2022-06-01 16:37:19 +00:00
self . log . info ( " cycle done " )
2022-08-23 14:00:04 +00:00
if " vision " in self . data :
2022-10-03 11:48:59 +00:00
vision_test_1 = self . data . get ( " vision " , { } ) . get ( " 0 " , { } )
2022-08-23 14:00:04 +00:00
out_paths = self . components [ " vision_saver " ] . save (
save_time = vision_test_1 . get ( " time " , None ) ,
frame = vision_test_1 . get ( " frame " , None ) ,
# vision=vision_test_1.get("detections", None),
)
2022-10-03 11:48:59 +00:00
self . data . get ( " vision " , { } ) . get ( " 0 " , { } ) [ " files " ] = out_paths
2022-08-23 14:00:04 +00:00
self . log . info ( f " cycle vision saved locally: { out_paths !r} " )
for vision in self . data . get ( " vision " , { } ) . values ( ) :
vision . pop ( " frame " , None )
vision . pop ( " render " , None )
2022-11-15 16:17:59 +00:00
if self . autotesting :
self . data [ " autotest " ] = True
self . data [ " autotest_reason " ] = self . autotesting_reason
2022-10-25 13:38:18 +00:00
archived = Archive . archive ( self . data , ok and self . data [ " ok " ] , overridden = self . data [ " overridden " ] )
2022-06-01 16:37:19 +00:00
self . log . info ( f " cycle archived locally: { archived !r} " )
2022-11-15 16:17:59 +00:00
if not self . autotesting :
# COUNT OK
if ok :
self . pieces [ " ok " ] + = 1
else :
self . pieces [ " ko " ] + = 1
2022-07-26 10:24:53 +00:00
return archived
2022-09-14 14:53:55 +00:00
@staticmethod
def labellify ( v ) :
2022-10-19 10:59:16 +00:00
if v is None :
v = " - "
elif isinstance ( v , float ) :
2022-10-03 14:52:05 +00:00
v = f " { v : .1f } "
2022-10-19 11:02:12 +00:00
if not isinstance ( v , str ) :
v = str ( v )
2022-09-14 14:53:55 +00:00
return v
2022-09-06 13:15:01 +00:00
def print ( self , archived , label ) :
2022-07-26 10:24:53 +00:00
self . log . info ( " cycle print " )
2022-09-14 14:53:55 +00:00
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 " )
2022-06-01 16:37:19 +00:00
# LABEL PRINT
2022-09-14 14:53:55 +00:00
recipe = archived . test_data . get ( " recipe " , { } )
2022-10-03 11:48:59 +00:00
leak_test_1 = archived . test_data . get ( " leak " , { } ) . get ( " 0 " , { } )
2022-09-14 14:53:55 +00:00
leak_test_1_step = leak_test_1 . get ( " step " , { } )
leak_test_1_step_spec = leak_test_1_step . get ( " spec " , { } )
2022-08-02 16:15:30 +00:00
leak_test_1_results = leak_test_1 . get ( " results " , { } )
leak_test_1_results_data = leak_test_1_results . get ( " data " , { } )
2022-07-26 10:24:53 +00:00
context = {
2022-09-14 14:53:55 +00:00
# RECIPE DATA
" RECIPE " : self . labellify ( recipe . get ( " name " , " - " ) ) ,
" 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
2022-08-01 11:29:12 +00:00
" DATETIME " : archived . time . strftime ( " %d / % m/ % Y % H: % M: % S " ) ,
2022-09-22 17:25:31 +00:00
" DATE " : archived . time . strftime ( " %d / % m/ % Y " ) ,
" TIME " : archived . time . strftime ( " % H: % M: % S " ) ,
2022-09-14 14:53:55 +00:00
" 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
2022-07-26 14:18:44 +00:00
" SHIFT " : str ( get_shift ( archived . time ) ) ,
2022-09-20 15:42:59 +00:00
" STATION " : str ( self . config . machine_id ) ,
2022-09-14 14:53:55 +00:00
" OPERATOR " : str ( archived . user . username ) ,
# RESULT
" RESULT " : str ( " CONFORME " if leak_test_1_results . get ( " ok " , False ) else " SCARTO " ) + str ( " FORZATO " if self . data . get ( " overridden " , False ) else " " ) ,
2022-07-27 12:54:19 +00:00
" RESULT_L1 " : " ESITO " + str ( " FORZATO " if self . data . get ( " overridden " , False ) else " " ) ,
2022-08-02 16:15:30 +00:00
" RESULT_L2 " : str ( " CONFORME " if leak_test_1_results . get ( " ok " , False ) else " SCARTO " ) ,
2022-07-26 10:24:53 +00:00
}
2022-09-14 14:53:55 +00:00
compiled_label = self . components [ " label_printer " ] . print_label ( label , context = context )
2022-07-26 10:24:53 +00:00
self . log . info ( f " cycle printed: { context !r} " )
2022-09-14 14:53:55 +00:00
return compiled_label