Merge remote-tracking branch 'origin/master'
# Conflicts: # runme_custom.sh
This commit is contained in:
commit
bb01c51eeb
Binary file not shown.
BIN
config/label_designs/STANDARD/EtichettaR5_Pitesti.nlbl
Normal file
BIN
config/label_designs/STANDARD/EtichettaR5_Pitesti.nlbl
Normal file
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
SIZE 37.5 mm, 130 mm
|
||||
SIZE 27.5 mm, 50 mm
|
||||
GAP 3 mm, 0 mm
|
||||
SPEED 2
|
||||
DENSITY 7
|
||||
|
|
@ -10,10 +10,9 @@ SET CUTTER OFF
|
|||
SET PARTIAL_CUTTER OFF
|
||||
SET TEAR ON
|
||||
CLS
|
||||
DMATRIX 116,270,184,184,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 82,230,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
CODEPAGE 1252
|
||||
TEXT 261,377,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 116,175,184,184,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 116,78,184,184,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
BOX 13,16,287,401,3
|
||||
TEXT 212,357,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 82,129,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 82,28,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
PRINT 1,1
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ SET TEAR ON
|
|||
CLS
|
||||
DMATRIX 82,230,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
CODEPAGE 1252
|
||||
TEXT 212,357,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}"
|
||||
TEXT 212,357,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 82,129,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
DMATRIX 82,28,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
|
||||
PRINT 1,1
|
||||
|
|
|
|||
|
|
@ -18,25 +18,25 @@
|
|||
^XZ
|
||||
^XA
|
||||
^MMT
|
||||
^PW320
|
||||
^LL1119
|
||||
^PW496
|
||||
^LL1559
|
||||
^LS0
|
||||
^FT33,86^A0N,45,46^FH\^CI28^FDERRECINQUE^FS^CI27
|
||||
^BY2,3,56^FT44,310^BCN,,N,N
|
||||
^FT61,119^A0N,67,68^FH\^CI28^FDERRECINQUE^FS^CI27
|
||||
^BY2,3,83^FT77,430^BCN,,N,N
|
||||
^FH\^FD>:{PART}^FS
|
||||
^FT15,347^A0N,31,30^FH\^CI28^FDPart number:^FS^CI27
|
||||
^FT15,427^A0N,31,30^FH\^CI28^FD{PART}^FS^CI27
|
||||
^FT17,136^A0N,17,18^FH\^CI28^FDVia Meucci 31/A - 10079 Mappano(TO)^FS^CI27
|
||||
^FT53,193^A0N,39,38^FH\^CI28^FDFPT^FS^CI27
|
||||
^FT53,235^A0N,39,38^FH\^CI28^FDLEAK TEST^FS^CI27
|
||||
^FT15,387^A0N,31,30^FH\^CI28^FD{DESCRIPTION}^FS^CI27
|
||||
^FT15,740^A0N,31,30^FH\^CI28^FDSequential number:^FS^CI27
|
||||
^FT15,779^A0N,31,30^FH\^CI28^FD{SN5}^FS^CI27
|
||||
^FT15,856^A0N,17,18^FH\^CI28^FD{DD}/{MM}/{YY}^FS^CI27
|
||||
^FT161,856^A0N,17,18^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
|
||||
^FT17,1081^A0N,31,30^FH\^CI28^FDESITO:^FS^CI27
|
||||
^FT143,1081^A0N,31,30^FH\^CI28^FDCONFORME^FS^CI27
|
||||
^FT15,934^A0N,25,25^FH\^CI28^FDOperatore^FS^CI27
|
||||
^FT15,967^A0N,25,25^FH\^CI28^FD{OPERATOR}^FS^CI27
|
||||
^FT34,482^A0N,46,46^FH\^CI28^FDPart number:^FS^CI27
|
||||
^FT34,595^A0N,46,46^FH\^CI28^FD{PART}^FS^CI27
|
||||
^FT37,172^A0N,25,25^FH\^CI28^FDVia Meucci 31/A - 10079 Mappano(TO)^FS^CI27
|
||||
^FT91,256^A0N,58,56^FH\^CI28^FDFPT^FS^CI27
|
||||
^FT91,312^A0N,58,56^FH\^CI28^FDLEAK TEST^FS^CI27
|
||||
^FT34,530^A0N,46,46^FH\^CI28^FD{DESCRIPTION}^FS^CI27
|
||||
^FT34,1243^A0N,46,46^FH\^CI28^FDSequential number:^FS^CI27
|
||||
^FT34,1291^A0N,46,46^FH\^CI28^FD{SN5}^FS^CI27
|
||||
^FT34,1361^A0N,33,33^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
|
||||
^FT250,1361^A0N,33,33^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
|
||||
^FT37,1487^A0N,46,46^FH\^CI28^FDCHECK:^FS^CI27
|
||||
^FT223,1487^A0N,46,46^FH\^CI28^FDCONFORME^FS^CI27
|
||||
^FT34,1427^A0N,38,38^FH\^CI28^FDOperatore^FS^CI27
|
||||
^FT223,1427^A0N,38,38^FH\^CI28^FD{OPERATOR}^FS^CI27
|
||||
^PQ1,0,1,Y
|
||||
^XZ
|
||||
|
|
|
|||
45
config/label_templates/EtichettaR5_Pitesti.prn
Normal file
45
config/label_templates/EtichettaR5_Pitesti.prn
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
CT~~CD,~CC^~CT~
|
||||
^XA
|
||||
~TA000
|
||||
~JSN
|
||||
^LT0
|
||||
^MNW
|
||||
^MTT
|
||||
^PON
|
||||
^PMN
|
||||
^LH0,0
|
||||
^JMA
|
||||
^PR2,2
|
||||
~SD22
|
||||
^JUS
|
||||
^LRN
|
||||
^CI27
|
||||
^PA0,1,1,0
|
||||
^XZ
|
||||
^XA
|
||||
^MMT
|
||||
^PW320
|
||||
^LL1119
|
||||
^LS0
|
||||
^FT57,105^A0N,39,38^FH\^CI28^FDERRECINQUE^FS^CI27
|
||||
^FT58,148^A0N,20,20^FH\^CI28^FDVia Meucci 31/A^FS^CI27
|
||||
^FT58,173^A0N,20,20^FH\^CI28^FD10079 Mappano(TO)^FS^CI27
|
||||
^FT18,758^A0N,23,20^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
|
||||
^FT183,758^A0N,23,20^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
|
||||
^FT18,981^A0N,31,30^FH\^CI28^FDESITO:^FS^CI27
|
||||
^FT144,981^A0N,31,30^FH\^CI28^FDCONFORME^FS^CI27
|
||||
^FT24,471^A0N,25,25^FH\^CI28^FDPart number:^FS^CI27
|
||||
^FT24,513^A0N,23,23^FH\^CI28^FD{PART}^FS^CI27
|
||||
^FT24,555^A0N,25,25^FH\^CI28^FDSequential number:^FS^CI27
|
||||
^FT24,598^A0N,23,23^FH\^CI28^FD{SN4}^FS^CI27
|
||||
^FT18,833^A0N,23,23^FH\^CI28^FDOperatore:^FS^CI27
|
||||
^FT157,674^A0N,23,23^FH\^CI28^FD{RESLEAK} mbar^FS^CI27
|
||||
^FT18,674^A0N,23,23^FH\^CI28^FD{TTEST} s^FS^CI27
|
||||
^FT18,724^A0N,23,23^FH\^CI28^FD{PTEST} mbar^FS^CI27
|
||||
^BY1,3,64^FT58,384^BCN,,N,N
|
||||
^FH\^FD>:{PART}^FS
|
||||
^FT58,241^A0N,25,25^FH\^CI28^FD{DESCRIPTION}^FS^CI27
|
||||
^FT58,292^A0N,45,46^FH\^CI28^FDLEAK TEST^FS^CI27
|
||||
^FT165,833^A0N,23,23^FH\^CI28^FD{BADGE_NUM}^FS^CI27
|
||||
^PQ1,0,1,Y
|
||||
^XZ
|
||||
|
|
@ -162,9 +162,9 @@ settling_time: 5
|
|||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_time: 10
|
||||
test_pressure_min_delta: 5
|
||||
test_pressure_qneg: 5
|
||||
test_pressure: 9000
|
||||
test_pressure_max_delta: 5
|
||||
test_pressure_qpos: 5
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
ST-TEN-1: st-ten-1
|
||||
ST-TEN-2: st-ten-2
|
||||
stten3: st-ten-3
|
||||
stten4: st-ten-4
|
||||
ST-TEN-4: st-ten-4
|
||||
st-ten-5: st-ten-5
|
||||
st-ten-6: st-ten-6
|
||||
st-ten-7: st-ten-7
|
||||
st-ten-8: st-ten-8
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ neo_pixels: present
|
|||
remote_api: absent
|
||||
tecna_t3: present
|
||||
vision_saver: present
|
||||
vision: absent
|
||||
vision: present
|
||||
screwdriver: present
|
||||
|
||||
[tecna_t3]
|
||||
|
|
@ -29,3 +29,67 @@ description_field: descrizione
|
|||
[label_printer]
|
||||
platform: windows
|
||||
printer: zd420
|
||||
|
||||
[recipes_defaults]
|
||||
|
||||
|
||||
codice_ricetta: specificare ricetta
|
||||
cliente: IVECO
|
||||
part_number: specificare part number
|
||||
config_elettrovalvole: 0
|
||||
warning_img:
|
||||
|
||||
dimensione_lotto_abilitata:
|
||||
|
||||
istruzione_abilitata: x
|
||||
numero nastri (n):0
|
||||
numero sensori anello (sa):0
|
||||
numero sensori presenza (sp):0
|
||||
|
||||
prova_tenuta_abilitata: x
|
||||
tempo_pre_riempimento: 0
|
||||
pressione_pre_riempimento: 5000
|
||||
tempo_riempimento: 5
|
||||
tempo_assestamento: 10
|
||||
percentuale_minima_pressione_assestamento: 5
|
||||
percentuale_massima_pressione_assestamento: 5
|
||||
tempo_di_test: 10
|
||||
pressione_di_test_delta_minimo: 30
|
||||
pressione_di_test: 5000
|
||||
pressione_di_test_delta_massimo: 30
|
||||
tempo_svuotamento: 1
|
||||
pressione_svuotamento: 100
|
||||
|
||||
prova_tenuta_abilitata_2:
|
||||
tempo_pre_riempimento_2: 0
|
||||
pressione_pre_riempimento_2: 1000
|
||||
tempo_riempimento_2: 5
|
||||
tempo_assestamento_2: 5
|
||||
percentuale_minima_pressione_assestamento_2: 5
|
||||
percentuale_massima_pressione_assestamento_2: 5
|
||||
tempo_di_test_2: 5
|
||||
pressione_di_test_delta_minimo_2: 200
|
||||
pressione_di_test_2: 1000
|
||||
pressione_di_test_delta_massimo_2: 200
|
||||
tempo_svuotamento_2: 1
|
||||
pressione_svuotamento_2: 100
|
||||
|
||||
stampa_etichetta_abilitata: x
|
||||
modello_etichetta: ETA30x16_203dpi.prn
|
||||
descrizione: inserire descrizione ricetta
|
||||
|
||||
[autotest_leak]
|
||||
enabled: true
|
||||
pre_filling_time: 0
|
||||
pre_filling_pressure: 1000
|
||||
filling_time: 15
|
||||
settling_time: 10
|
||||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_time: 10
|
||||
test_pressure_qneg: 10
|
||||
test_pressure: 7000
|
||||
test_pressure_qpos: 5
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
relay_config: 1
|
||||
|
|
@ -39,3 +39,19 @@ pressione_di_test_delta_massimo: 30
|
|||
tempo_svuotamento: 1
|
||||
pressione_svuotamento: 100
|
||||
config_elettrovalvole: 0
|
||||
|
||||
[autotest_leak]
|
||||
enabled: true
|
||||
pre_filling_time: 0
|
||||
pre_filling_pressure: 1000
|
||||
filling_time: 5
|
||||
settling_time: 10
|
||||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_time: 10
|
||||
test_pressure_qneg: 5
|
||||
test_pressure: 9000
|
||||
test_pressure_qpos: 5
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
relay_config: 1
|
||||
|
|
@ -10,6 +10,7 @@ remote_api: absent
|
|||
tecna_t3: present
|
||||
digital_io: present
|
||||
barcode_recipe_selection: present
|
||||
show_instructions: yes
|
||||
|
||||
[tecna_t3]
|
||||
port: COM4
|
||||
|
|
@ -90,9 +91,9 @@ settling_time: 10
|
|||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_time: 10
|
||||
test_pressure_min_delta: 10
|
||||
test_pressure_qneg: 10
|
||||
test_pressure: 5000
|
||||
test_pressure_max_delta: 5
|
||||
test_pressure_qpos: 5
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
relay_config: 1
|
||||
|
|
@ -3,8 +3,7 @@ description = ST-TEN-6 DOPPIA PROVA PRESSIONE 6/20 BAR
|
|||
|
||||
[hardware_config]
|
||||
archive_synchronizer: present
|
||||
; galaxy_camera: present
|
||||
uvc_camera: present
|
||||
uvc_camera: absent
|
||||
label_printer: present
|
||||
neo_pixels: present
|
||||
remote_api: absent
|
||||
|
|
@ -28,6 +27,7 @@ printer: zd421
|
|||
|
||||
[digital_io]
|
||||
id: USB-5860,BID#0
|
||||
|
||||
[recipe]
|
||||
recipe_name_field: codice_ricetta
|
||||
part_number_field: codice_prodotto
|
||||
|
|
@ -38,8 +38,8 @@ description_field: descrizione
|
|||
dimensione_lotto_abilitata:
|
||||
tempo_pre_riempimento: 0
|
||||
pressione_pre_riempimento: 1000
|
||||
tempo_riempimento: 15
|
||||
tempo_assestamento: 15
|
||||
tempo_riempimento: 10
|
||||
tempo_assestamento: 10
|
||||
tempo_di_test: 10
|
||||
percentuale_minima_pressione_assestamento: 5
|
||||
percentuale_massima_pressione_assestamento: 5
|
||||
|
|
@ -52,8 +52,8 @@ config_elettrovalvole: 1
|
|||
prova_tenuta_abilitata_2:
|
||||
tempo_pre_riempimento_2: 0
|
||||
pressione_pre_riempimento_2: 1000
|
||||
tempo_riempimento_2: 20
|
||||
tempo_assestamento_2: 20
|
||||
tempo_riempimento_2: 10
|
||||
tempo_assestamento_2: 10
|
||||
tempo_di_test_2: 10
|
||||
percentuale_minima_pressione_assestamento_2: 5
|
||||
percentuale_massima_pressione_assestamento_2: 5
|
||||
|
|
@ -69,14 +69,16 @@ modello_etichetta: EtichettaR5_Montaggio_1prova.prn
|
|||
enabled: true
|
||||
pre_filling_time: 0
|
||||
pre_filling_pressure: 1000
|
||||
filling_time: 15
|
||||
filling_time: 10
|
||||
settling_time: 10
|
||||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_pressure: 7000
|
||||
test_time: 10
|
||||
test_pressure_min_delta: 35
|
||||
test_pressure: 15000
|
||||
test_pressure_max_delta: 5
|
||||
test_pressure_qpos: 5 #Q+ Upper test leak limit
|
||||
test_pressure_qneg: 15 #Q- Lower test leak limit
|
||||
test_pressure_tt_qpos: 0 # Q+ Upper test leak limit (tube-tube)
|
||||
test_pressure_tt_qneg: 5 # Q- Lower test leak limit (tube-tube)
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
relay_config: 1
|
||||
82
config/machine_settings/st-ten-7.ini
Normal file
82
config/machine_settings/st-ten-7.ini
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
[machine]
|
||||
description = ST-TEN-7 SECONDO BANCO IVECO DAILY ELETTRICO
|
||||
|
||||
[hardware_config]
|
||||
archive_synchronizer: present
|
||||
uvc_camera: absent
|
||||
label_printer: present
|
||||
neo_pixels: present
|
||||
remote_api: absent
|
||||
tecna_t3: present
|
||||
vision_saver: absent
|
||||
vision: absent
|
||||
screwdriver: absent
|
||||
digital_io: present
|
||||
second_leak_test: present
|
||||
|
||||
[tecna_t3]
|
||||
port: COM4
|
||||
model: t3l
|
||||
|
||||
[neo_pixels]
|
||||
port: COM5
|
||||
|
||||
[label_printer]
|
||||
platform: windows
|
||||
printer: zd421
|
||||
|
||||
[digital_io]
|
||||
id: USB-5860,BID#0
|
||||
|
||||
[recipe]
|
||||
recipe_name_field: codice_ricetta
|
||||
part_number_field: codice_prodotto
|
||||
label_template_field: modello_etichetta
|
||||
description_field: descrizione
|
||||
|
||||
[recipes_defaults]
|
||||
dimensione_lotto_abilitata:
|
||||
tempo_pre_riempimento: 0
|
||||
pressione_pre_riempimento: 1000
|
||||
tempo_riempimento: 15
|
||||
tempo_assestamento: 15
|
||||
tempo_di_test: 10
|
||||
percentuale_minima_pressione_assestamento: 5
|
||||
percentuale_massima_pressione_assestamento: 5
|
||||
pressione_di_test_delta_minimo: 30
|
||||
pressione_di_test: 7000
|
||||
pressione_di_test_delta_massimo: 30
|
||||
tempo_svuotamento: 1
|
||||
pressione_svuotamento: 100
|
||||
config_elettrovalvole: 1
|
||||
prova_tenuta_abilitata_2:
|
||||
tempo_pre_riempimento_2: 0
|
||||
pressione_pre_riempimento_2: 1000
|
||||
tempo_riempimento_2: 20
|
||||
tempo_assestamento_2: 20
|
||||
tempo_di_test_2: 10
|
||||
percentuale_minima_pressione_assestamento_2: 5
|
||||
percentuale_massima_pressione_assestamento_2: 5
|
||||
pressione_di_test_delta_minimo_2: 30
|
||||
pressione_di_test_2: 15000
|
||||
pressione_di_test_delta_massimo_2: 30
|
||||
tempo_svuotamento_2: 1
|
||||
pressione_svuotamento_2: 100
|
||||
config_elettrovalvole_2: 2
|
||||
modello_etichetta: EtichettaR5_Montaggio_1prova.prn
|
||||
|
||||
[autotest_leak]
|
||||
enabled: true
|
||||
pre_filling_time: 0
|
||||
pre_filling_pressure: 1000
|
||||
filling_time: 15
|
||||
settling_time: 10
|
||||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_time: 10
|
||||
test_pressure_qneg: 35
|
||||
test_pressure: 15000
|
||||
test_pressure_qpos: 5
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
relay_config: 1
|
||||
85
config/machine_settings/st-ten-8.ini
Normal file
85
config/machine_settings/st-ten-8.ini
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
[machine]
|
||||
description = ST-TEN-8 DAILY AUTOMATICO
|
||||
|
||||
[hardware_config]
|
||||
archive_synchronizer: present
|
||||
uvc_camera: absent
|
||||
label_printer: present
|
||||
neo_pixels: absent
|
||||
remote_api: absent
|
||||
tecna_t3: present
|
||||
vision_saver: absent
|
||||
vision: absent
|
||||
screwdriver: absent
|
||||
digital_io: present
|
||||
second_leak_test: absent
|
||||
fixture_id: present
|
||||
discard_box: present
|
||||
|
||||
[tecna_t3]
|
||||
port: COM4
|
||||
model: t3l
|
||||
|
||||
[label_printer]
|
||||
platform: windows
|
||||
printer: zd421
|
||||
|
||||
[digital_io]
|
||||
id: USB-5860,BID#0
|
||||
discard_idx:15 # BIT NUMBER OF THE I/0 MODULE USED FOR DISCARD SENSING
|
||||
|
||||
[fixture_rfid]
|
||||
port: COM5
|
||||
|
||||
[recipe]
|
||||
recipe_name_field: codice_ricetta
|
||||
part_number_field: codice_prodotto
|
||||
label_template_field: modello_etichetta
|
||||
description_field: descrizione
|
||||
|
||||
[recipes_defaults]
|
||||
dimensione_lotto_abilitata:
|
||||
tempo_pre_riempimento: 0
|
||||
pressione_pre_riempimento: 1000
|
||||
tempo_riempimento: 15
|
||||
tempo_assestamento: 15
|
||||
tempo_di_test: 10
|
||||
percentuale_minima_pressione_assestamento: 5
|
||||
percentuale_massima_pressione_assestamento: 5
|
||||
pressione_di_test_delta_minimo: 30
|
||||
pressione_di_test: 7000
|
||||
pressione_di_test_delta_massimo: 30
|
||||
tempo_svuotamento: 1
|
||||
pressione_svuotamento: 100
|
||||
config_elettrovalvole: 1
|
||||
prova_tenuta_abilitata_2:
|
||||
tempo_pre_riempimento_2: 0
|
||||
pressione_pre_riempimento_2: 1000
|
||||
tempo_riempimento_2: 20
|
||||
tempo_assestamento_2: 20
|
||||
tempo_di_test_2: 10
|
||||
percentuale_minima_pressione_assestamento_2: 5
|
||||
percentuale_massima_pressione_assestamento_2: 5
|
||||
pressione_di_test_delta_minimo_2: 30
|
||||
pressione_di_test_2: 15000
|
||||
pressione_di_test_delta_massimo_2: 30
|
||||
tempo_svuotamento_2: 1
|
||||
pressione_svuotamento_2: 100
|
||||
config_elettrovalvole_2: 2
|
||||
modello_etichetta: EtichettaR5_Montaggio_1prova.prn
|
||||
|
||||
[autotest_leak]
|
||||
enabled: true
|
||||
pre_filling_time: 0
|
||||
pre_filling_pressure: 1000
|
||||
filling_time: 15
|
||||
settling_time: 10
|
||||
settling_pressure_min_percent: 5
|
||||
settling_pressure_max_percent: 5
|
||||
test_time: 10
|
||||
test_pressure_qneg: 35
|
||||
test_pressure: 15000
|
||||
test_pressure_qpos: 5
|
||||
flush_time: 1
|
||||
flush_pressure: 100
|
||||
relay_config: 1
|
||||
10
config/vision/labels/000952054.pbtxt
Normal file
10
config/vision/labels/000952054.pbtxt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
item {
|
||||
id: 1
|
||||
name: 'ok'
|
||||
color: '0x55AA55'
|
||||
}
|
||||
item {
|
||||
id: 2
|
||||
name: 'ko'
|
||||
color: '0xff0000'
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
item {
|
||||
id: 1
|
||||
name: 'hs-ok'
|
||||
name: 'ok'
|
||||
color: '0x55AA55'
|
||||
}
|
||||
item {
|
||||
id: 2
|
||||
name: 'hs-ko'
|
||||
name: 'ko'
|
||||
color: '0xff0000'
|
||||
}
|
||||
|
|
|
|||
10
config/vision/labels/termorestringente_923578.pbtxt
Normal file
10
config/vision/labels/termorestringente_923578.pbtxt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
item {
|
||||
id: 1
|
||||
name: 'hs-ok'
|
||||
color: '0x55AA55'
|
||||
}
|
||||
item {
|
||||
id: 2
|
||||
name: 'hs-ko'
|
||||
color: '0xff0000'
|
||||
}
|
||||
33
config/vision/recipes/000952054.ini
Normal file
33
config/vision/recipes/000952054.ini
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# O-RING PRESENCE DETECTOR
|
||||
# FOR FERRARI 000952054
|
||||
|
||||
[general]
|
||||
name: ORING
|
||||
instruction: CONTROLLARE PRESENZA N. 2 O-RING SU RACCORDI
|
||||
neural_network: od1-50000
|
||||
type: targeted
|
||||
|
||||
# POINTS FORMAT:
|
||||
# point_name: point_center point_size fill_color border_color border_thickness shape
|
||||
# EXAMPLE:
|
||||
# name: X,Y W,H 0xAARRGGBB 0xAARRGGBB T SHAPE CLASS
|
||||
# ZONES FORMAT:
|
||||
# region_name: region_center region_margin class
|
||||
# margin can be a box (XM*2,YM*2) or a radius (R)
|
||||
# EXAMPLES:
|
||||
# name: X,Y XM,YM T SHAPE CLASS
|
||||
# name: X,Y R T SHAPE CLASS
|
||||
# LABELS FORMAT:
|
||||
# label_name: label_start_location font_size fill_color border_color border_thickness text
|
||||
# EXAMPLE:
|
||||
# name: X,Y S 0xAARRGGBB 0xAARRGGBB T TEXT
|
||||
|
||||
[markers]
|
||||
|
||||
[zones]
|
||||
p1: 430,1140 520,260 ok
|
||||
p2: 2900,1140 520,260 ok
|
||||
|
||||
[labels]
|
||||
p1: 180,900 120 0xffffffff 0xff000000 4 O-RING 1
|
||||
p2: 2600,900 120 0xffffffff 0xff000000 4 O-RING 2
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
[general]
|
||||
name: TERMORESTRINGENTE
|
||||
instruction: CONTROLLARE PRESENZA TERMORESTRINGENTE
|
||||
neural_network: hs5-20000
|
||||
type: global
|
||||
|
||||
# POINTS FORMAT:
|
||||
# point_name: point_center point_size fill_color border_color border_thickness shape
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 144 KiB |
BIN
config/warning_images/generic/Img-10.png
Normal file
BIN
config/warning_images/generic/Img-10.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 892 KiB |
BIN
config/warning_images/generic/Img-11.png
Normal file
BIN
config/warning_images/generic/Img-11.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 341 KiB |
|
|
@ -2,7 +2,13 @@
|
|||
:: RUN FROM POWERSHELL W/ADMIN RIGHTS:
|
||||
:: Set-ExecutionPolicy Unrestricted -Scope CurrentUser
|
||||
|
||||
pip install -r src/requirements.txt
|
||||
|
||||
mkdir tmp
|
||||
cd tmp
|
||||
|
||||
:: Advantech XNAVI
|
||||
Invoke-WebRequest -uri "https://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-2BZC0F1" -usebasicparsing -outfile xnavi.zip
|
||||
|
||||
:: GXIPY
|
||||
Invoke-WebRequest -uri "https://dahengimaging.com/downloads/Galaxy_Windows_EN_32bits%2064bits_1.18.2208.9301.zip" -OutFile Galaxy_Windows_EN_32bits_64bits_1.18.2208.9301.zip
|
||||
Invoke-WebRequest -uri "https://dahengimaging.com/downloads/Galaxy_Windows_EN_32bits%2064bits_1.18.2208.9301.zip" -usebasicparsing -OutFile Galaxy_Windows_EN_32bits_64bits_1.18.2208.9301.zip
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
cd "$(dirname "$0")"
|
||||
source "./venv/bin/activate" || source "./venv/Scripts/activate" || :
|
||||
python -O "./src/main.py" --auto-accept-test-admin-permission --auto-login-admin --no-edgetpu --no-gpu --panel --system-id=st-ten-5 --no-autotest --sim-camera --sim-modbus --sim-os-label-printer --sim-serial --style windows $*
|
||||
4
runme_noautotest.bat
Normal file
4
runme_noautotest.bat
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
echo on
|
||||
SET mypath=%~dp0
|
||||
cd %mypath%
|
||||
.\venv\Scripts\activate.bat && python -O "./src/main.py" --no-edgetpu --no-tflite --no-autotest
|
||||
42
src/components/rfid.py
Normal file
42
src/components/rfid.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import ctypes
|
||||
import sys
|
||||
import platform
|
||||
from PyQt5.QtCore import QMutex, Qt, QTimer, pyqtSlot, pyqtSignal
|
||||
from .component import Component
|
||||
import nfc
|
||||
from nfc.clf import RemoteTarget
|
||||
|
||||
|
||||
|
||||
is_win = platform.system() == "Windows"
|
||||
|
||||
class RFID(Component):
|
||||
def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True):
|
||||
super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
|
||||
self.mutex = QMutex()
|
||||
self.simulate="--sim-rfid" in sys.argv
|
||||
self.clf = nfc.ContactlessFrontend()
|
||||
|
||||
def open_device(self):
|
||||
self.clf.open('tty:USB0:pn532')
|
||||
|
||||
def close_device(self):
|
||||
pass
|
||||
|
||||
@pyqtSlot()
|
||||
def start(self):
|
||||
# ACQUISITION TIMER
|
||||
self.timer = QTimer()
|
||||
self.timer.setTimerType(Qt.PreciseTimer)
|
||||
self.timer.setInterval(int(1000 / 20))
|
||||
self.timer.timeout.connect(self.get)
|
||||
self.timer.start()
|
||||
super().start()
|
||||
|
||||
@pyqtSlot()
|
||||
def get(self):
|
||||
data=None
|
||||
if data is not None:
|
||||
super()._get([data])
|
||||
|
||||
|
||||
|
|
@ -205,15 +205,16 @@ class TecnaMarpossProvasetT3(ModbusComponent):
|
|||
# READ INFO
|
||||
info = {r: self.read(r) for r in [
|
||||
"Real time test pressure output",
|
||||
"Real time differential pressure output",
|
||||
"Real time pressure line regulator",
|
||||
"Active alarm flags",
|
||||
"Active test program number",
|
||||
#"Real time differential pressure output",
|
||||
#"Active alarm flags",
|
||||
#"Active test program number",
|
||||
"Running test: active phase",
|
||||
"Running test: test type",
|
||||
"Running test: measured leak",
|
||||
"Running test: sequence index",
|
||||
"Digital inputs status (mask)",
|
||||
# "Digital outputs status (mask)",
|
||||
"Digital outputs status (mask)",
|
||||
]}
|
||||
if self.model == "t3p":
|
||||
pass
|
||||
|
|
@ -222,9 +223,12 @@ class TecnaMarpossProvasetT3(ModbusComponent):
|
|||
"Active not severe alarm flags",
|
||||
]})
|
||||
else:
|
||||
raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.")
|
||||
raise NotImplementedError(f"Tecna t3 model {self.model!r} not implemented.")
|
||||
if info["Running test: active phase"] == "FINE TEST": # "END TEST, WAITING THE START OF A NEW TEST":
|
||||
info.update(self.get_test_results())
|
||||
for round_me in ["measured leak"]:
|
||||
if round_me in info.keys():
|
||||
info.update({round_me:float(f"{info[round_me]:.2f}")})
|
||||
self.log.debug(str(info))
|
||||
super()._get([info])
|
||||
|
||||
|
|
@ -251,13 +255,13 @@ class TecnaMarpossProvasetT3(ModbusComponent):
|
|||
def get_test_results(self):
|
||||
self.log.info("getting test results")
|
||||
return {r: self.read(r) for r in [
|
||||
"Running test: phase backwards time",
|
||||
#"Running test: phase backwards time",
|
||||
"Running test: filling pressure",
|
||||
"Running test: pressure at the end of settling",
|
||||
"Running test: burst pressure",
|
||||
#"Running test: burst pressure",
|
||||
"Running test: measured leak",
|
||||
"Running test: calculated leak flow rate",
|
||||
"Running test: calculate RVP%",
|
||||
#"Running test: calculated leak flow rate",
|
||||
#"Running test: calculate RVP%",
|
||||
"Running test: result",
|
||||
]}
|
||||
|
||||
|
|
@ -277,7 +281,8 @@ class TecnaMarpossProvasetT3(ModbusComponent):
|
|||
# **{769 - 1 + i: (recipe_name[i * 2 + 1] << 8) + recipe_name[i * 2] for i in range(8)}, # print field 2
|
||||
"Print options": 0b0000000000000000 | self.saver_label_count << 12 | self.saver_print_on_fail << 8 | self.saver_label_template,
|
||||
"Test type": "Leak Test",
|
||||
"Test flags": 0b0110000001011100 if step.spec.get("autotest", False) is not True else 0b0110000001010100,
|
||||
# "Test flags": 0b0110000001011100 if step.spec.get("autotest", False) is not True else 0b0110000001010100,
|
||||
"Test flags": 0b0110100001010100 if step.spec.get("autotest", False) in ("ok_check","ko_check") else 0b0110000001010100,
|
||||
"T0 - Pre-filling time": step.spec["pre_filling_time"],
|
||||
"P0 - Pre-filling pressure": step.spec["pre_filling_pressure"],
|
||||
"T1 - Filling time": step.spec["filling_time"],
|
||||
|
|
@ -285,9 +290,9 @@ class TecnaMarpossProvasetT3(ModbusComponent):
|
|||
"PR- - Min pressure tolerance %": step.spec["settling_pressure_min_percent"],
|
||||
"PR+ - Max pressure tolerance % (P+)": step.spec["settling_pressure_max_percent"],
|
||||
"T3 - Measure time": step.spec["test_time"],
|
||||
"Q- Lower test leak limit": step.spec["test_pressure_min_delta"],
|
||||
"Q- Lower test leak limit": step.spec["test_pressure_qneg"],
|
||||
"PREL - Nominal test pressure": step.spec["test_pressure"],
|
||||
"Q+ Upper test leak limit": step.spec["test_pressure_max_delta"],
|
||||
"Q+ Upper test leak limit": step.spec["test_pressure_qpos"],
|
||||
"FST - Discharge time": step.spec["flush_time"],
|
||||
"FSL - Discharge limit": step.spec["flush_pressure"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ registers = {
|
|||
"Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 1507, }],
|
||||
"Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }],
|
||||
"Running test: result": [46 - 1, {"dt": "16bit_uint", "decoding": {
|
||||
1: "LEAK TEST PASSED (also used in Volume+Leak tests)",
|
||||
1: "LEAK TEST PASSED",
|
||||
2: "BURST TEST PASSED WITH BURST",
|
||||
3: "BURST TEST PASSED WITHOUT BURST",
|
||||
4: "APERTURE TEST PASSED",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ registers = {
|
|||
"Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 24, }],
|
||||
"Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }],
|
||||
"Running test: result": [46 - 1, {"dt": "16bit_uint", "decoding": {
|
||||
1: "LEAK TEST PASSED (also used in Volume+Leak tests)",
|
||||
1: "LEAK TEST PASSED",
|
||||
2: "BURST TEST PASSED WITH BURST",
|
||||
3: "BURST TEST PASSED WITHOUT BURST",
|
||||
4: "APERTURE TEST PASSED",
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ else:
|
|||
|
||||
|
||||
class Vision(Component):
|
||||
"""everything is expected the have shape with height (y) first then width (x)"""
|
||||
"""everything is expected to have shape with height (y) first then width (x)"""
|
||||
|
||||
status_signal = pyqtSignal(object)
|
||||
loading_model_signal = pyqtSignal(object)
|
||||
|
|
@ -66,6 +66,7 @@ class Vision(Component):
|
|||
super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
|
||||
self.lock = QMutex()
|
||||
self.simulate = "--sim-vision" in sys.argv
|
||||
self.vision_config = None
|
||||
|
||||
def start(self):
|
||||
self.model = None
|
||||
|
|
@ -96,7 +97,7 @@ class Vision(Component):
|
|||
self.render_consumer.out.connect(self.process_render_consumed)
|
||||
super().start()
|
||||
|
||||
def config_changed(self):
|
||||
def config_changed(self,vision_recipe=None):
|
||||
# OBJECT DETECTION
|
||||
self.detection_threshold = float(self.config[self.name].get("detection_threshold", 0.5))
|
||||
# recipe
|
||||
|
|
@ -104,7 +105,8 @@ class Vision(Component):
|
|||
self.labels = None
|
||||
# LOAD RECIPE
|
||||
self.recipes_dir = Path(self.config[self.name].get("recipes_dir", "./config/vision/recipes"))
|
||||
self.set_recipe(None)
|
||||
self.set_recipe(vision_recipe)
|
||||
self.vision_recipe=vision_recipe
|
||||
self.recipe_watcher = QFileSystemWatcher([])
|
||||
self.recipe_watcher.fileChanged.connect(self._set_recipe)
|
||||
# LOAD MODEL
|
||||
|
|
@ -119,9 +121,11 @@ class Vision(Component):
|
|||
if "--no-tflite" in sys.argv:
|
||||
self.allowed_modes.pop("edgetpu", None)
|
||||
self.allowed_modes.pop("tflite", None)
|
||||
self.load_model(self.config[self.name].get("neural_network", None))
|
||||
if self.vision_config is not None:
|
||||
self.load_model(self.vision_config["neural_network"])
|
||||
# LOAD LABELS
|
||||
label_map = label_map_util.load_labelmap("./config/vision/labels/labels.pbtxt")
|
||||
label_file="labels" if vision_recipe is None else vision_recipe
|
||||
label_map = label_map_util.load_labelmap(f"./config/vision/labels/{label_file}.pbtxt")
|
||||
self.num_classes = len(label_map.item)
|
||||
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=self.num_classes, use_display_name=True)
|
||||
self.category_index = label_map_util.create_category_index(categories)
|
||||
|
|
@ -148,7 +152,7 @@ class Vision(Component):
|
|||
return pow((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2, 1 / 2)
|
||||
|
||||
def clear_recipe(self):
|
||||
self.recipe = None
|
||||
self.recipe_name = None
|
||||
self.markers = {}
|
||||
self.zones = {}
|
||||
self.labels = {}
|
||||
|
|
@ -170,6 +174,7 @@ class Vision(Component):
|
|||
if len(read) != 1 or self.recipe_path not in read:
|
||||
raise AssertionError("Recipe could not be read.")
|
||||
os.path.splitext(os.path.basename(read[0]))[0]
|
||||
self.vision_config = config._sections.get("general", None)
|
||||
self.markers = self.parse_markers(config._sections.get("markers", None))
|
||||
self.zones = self.parse_zones(config._sections.get("zones", None))
|
||||
self.labels = self.parse_labels(config._sections.get("labels", None))
|
||||
|
|
@ -179,7 +184,7 @@ class Vision(Component):
|
|||
self.log.exception(f"Error reading {self.recipe_path!r}:")
|
||||
self.clear_recipe()
|
||||
self.status_signal.emit({
|
||||
"recipe": self.recipe,
|
||||
"recipe": self.recipe_name,
|
||||
"markers": self.markers,
|
||||
"zones": self.zones,
|
||||
"labels": self.labels,
|
||||
|
|
@ -189,8 +194,8 @@ class Vision(Component):
|
|||
if recipe is None:
|
||||
self.clear_recipe()
|
||||
else:
|
||||
self.recipe = recipe
|
||||
self._set_recipe(self.recipes_dir / str(recipe))
|
||||
self.recipe_name = recipe.split(".")[0]
|
||||
self._set_recipe(self.recipes_dir / f"{self.recipe_name}.ini")
|
||||
|
||||
def parse_markers(self, config=None):
|
||||
if config is None:
|
||||
|
|
@ -434,11 +439,104 @@ class Vision(Component):
|
|||
parsed_detections.append(detection)
|
||||
return parsed_detections
|
||||
|
||||
def check_features_targeted(self, frame, lock=True):
|
||||
parsed_detections = []
|
||||
for zone_name,zone in self.zones.items():
|
||||
y1,x1,y2,x2=int(zone["box"][0]),int(zone["box"][1]),int(zone["box"][2]),int(zone["box"][3])
|
||||
crop = frame[y1:y2,x1:x2]
|
||||
|
||||
if self.interpreter is not None and frame.shape != self.interpreter.get_input_details()[0]["shape"][1:3]:
|
||||
tensor = np.expand_dims(cv2.resize(crop, self.interpreter.get_input_details()[0]["shape"][1:3], interpolation=cv2.INTER_LINEAR), axis=0)
|
||||
else:
|
||||
frame_resized = cv2.resize(crop, (256, 256), interpolation=cv2.INTER_LINEAR)
|
||||
tensor = tf.convert_to_tensor(np.asarray(frame_resized))
|
||||
tensor = tensor[tf.newaxis, ...]
|
||||
# tensor = np.expand_dims(frame, axis=0)
|
||||
# Run inference
|
||||
if lock:
|
||||
self.lock.lock()
|
||||
if self.simulate or self.tf_mode == "simulation":
|
||||
detections = {
|
||||
"detection_scores": [[1.0]],
|
||||
"detection_boxes": [[[0.2, 0.2, 0.8, 0.8]]],
|
||||
"detection_classes": [[1]],
|
||||
}
|
||||
if lock:
|
||||
self.lock.unlock()
|
||||
elif self.tf_mode in {"edgetpu", "tflite"}:
|
||||
i_d = self.interpreter.get_input_details()
|
||||
# print(i_d)
|
||||
o_d = self.interpreter.get_output_details()
|
||||
# print(o_d)
|
||||
self.interpreter.set_tensor(i_d[0]["index"], tensor)
|
||||
self.interpreter.invoke()
|
||||
# PARSE TFLITE DETECTIONS
|
||||
# signature_list = self.interpreter._get_full_signature_list()
|
||||
# if signature_list:
|
||||
# if len(signature_list) > 1:
|
||||
# raise ValueError("Only support model with one signature.")
|
||||
# signature = signature_list[next(iter(signature_list))]
|
||||
# # count = int(self.interpreter.get_tensor(signature["outputs"]["output_0"])[0])
|
||||
# scores = self.interpreter.get_tensor(signature["outputs"]["output_1"])[0]
|
||||
# class_ids = self.interpreter.get_tensor(signature["outputs"]["output_2"])[0]
|
||||
# boxes = self.interpreter.get_tensor(signature["outputs"]["output_3"])[0]
|
||||
if self.interpreter.get_tensor(o_d[3]["index"]).size == 1:
|
||||
boxes = self.interpreter.get_tensor(o_d[0]["index"])[0]
|
||||
class_ids = self.interpreter.get_tensor(o_d[1]["index"])[0]
|
||||
scores = self.interpreter.get_tensor(o_d[2]["index"])[0]
|
||||
# count = int(self.interpreter.get_tensor(o_d[3]["index"])[0])
|
||||
else:
|
||||
scores = self.interpreter.get_tensor(o_d[0]["index"])[0]
|
||||
boxes = self.interpreter.get_tensor(o_d[1]["index"])[0]
|
||||
# count = int(self.interpreter.get_tensor(o_d[2]["index"])[0])
|
||||
class_ids = self.interpreter.get_tensor(o_d[3]["index"])[0]
|
||||
if lock:
|
||||
self.lock.unlock()
|
||||
detections = {
|
||||
"detection_scores": [scores],
|
||||
"detection_boxes": [boxes],
|
||||
"detection_classes": [map(lambda class_id: class_id + 1, class_ids)],
|
||||
}
|
||||
else:
|
||||
detections = self.model(tensor)
|
||||
if lock:
|
||||
self.lock.unlock()
|
||||
detections = {
|
||||
"detection_scores": detections["detection_scores"].numpy().tolist(),
|
||||
"detection_boxes": detections["detection_boxes"].numpy().tolist(),
|
||||
"detection_classes": detections["detection_classes"],
|
||||
}
|
||||
# WARNING: results other than the ones related to tensor[-1] will be discarded
|
||||
for d_score, d_box, d_class in zip( # , d_mask in zip(
|
||||
detections["detection_scores"][-1],
|
||||
detections["detection_boxes"][-1],
|
||||
detections["detection_classes"][-1],
|
||||
# detections["detection_masks"][-1],
|
||||
):
|
||||
if d_score < self.detection_threshold:
|
||||
continue
|
||||
box = list(d_box)
|
||||
box = [i * s for i, s in zip(box, crop.shape[:2] * 2)] # rescale detection to frame size
|
||||
box_real=[box[0]+y1,box[1]+x1,box[2]+y1,box[3]+x1]
|
||||
detection = {
|
||||
"score": d_score,
|
||||
"box": box_real,
|
||||
"class": self.category_index[int(d_class)],
|
||||
# "mask": d_mask,
|
||||
"center": self.get_center(box),
|
||||
"size": self.get_size(box),
|
||||
}
|
||||
|
||||
parsed_detections.append(detection)
|
||||
break # keep only first detection
|
||||
|
||||
return parsed_detections
|
||||
|
||||
def detections_to_items(self, detections):
|
||||
# DRAW DETECTIONS
|
||||
if detections is not None and len(detections):
|
||||
style = {
|
||||
"border_thickness": 25,
|
||||
"border_thickness": 5,
|
||||
"fill_color": QColor("#00000000"),
|
||||
"shape": "rect",
|
||||
"convert_negative_placement": False,
|
||||
|
|
@ -460,7 +558,7 @@ class Vision(Component):
|
|||
# MATCH DETECTIONS WITH RECIPE
|
||||
results = dict.fromkeys(self.zones)
|
||||
for detection in detections:
|
||||
# find closest zone center to the detection
|
||||
# find the closest zone center to the detection
|
||||
# filtering out those that do not contain the detection
|
||||
min_distance = sys.maxsize
|
||||
closest_zone = None
|
||||
|
|
@ -744,7 +842,11 @@ class Vision(Component):
|
|||
# VISION_CONSUMER TASK
|
||||
if consumable is None:
|
||||
return
|
||||
if self.vision_config["type"]=="targeted":
|
||||
detections = self.check_features_targeted(consumable["frame"])
|
||||
else:
|
||||
detections = self.check_features(consumable["frame"])
|
||||
|
||||
results = self.process_detections(detections)
|
||||
return {"detections": detections, "results": results}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ def init_db():
|
|||
# "connector": {"connector": row["connector"]},
|
||||
# "barcodes": {"serial": ""},
|
||||
# "resistance": {"scale": 500, "expected": float(row["resistance_expected"]), "tolerance": float(row["resistance_tolerance"])},
|
||||
# "leak_1": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_min_delta": 100, "test_pressure": 1000, "test_pressure_max_delta": 100, "flush_time": 1, "flush_pressure": 100},
|
||||
# "leak_2": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_min_delta": 100, "test_pressure": 1000, "test_pressure_max_delta": 100, "flush_time": 1, "flush_pressure": 100},
|
||||
# "leak_1": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
|
||||
# "leak_2": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
|
||||
# "vision": {"recipe": "termorestringente_923578.ini"},
|
||||
# "print": {"template": "EtichettaR5.prn", },
|
||||
# }.items():
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from .users import Users
|
|||
|
||||
class Archive(BaseModel):
|
||||
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)
|
||||
result = BooleanField(null=False)
|
||||
overridden = BooleanField(null=False)
|
||||
|
|
@ -22,7 +22,11 @@ class Archive(BaseModel):
|
|||
@classmethod
|
||||
@db.atomic()
|
||||
def archive(cls, test_data, result, overridden):
|
||||
time=datetime.now()
|
||||
test_data["time"]=time.strftime("%d/%m/%Y %H:%M:%S")
|
||||
test_data["user"]=Users.get_session().username
|
||||
return cls.create(
|
||||
time=time,
|
||||
user=Users.get_session().user,
|
||||
result=result,
|
||||
overridden=overridden,
|
||||
|
|
|
|||
|
|
@ -136,11 +136,9 @@ class Users(BaseModel):
|
|||
def delete_by_username(cls, username):
|
||||
cls.update(password="").where(cls.username == username).execute()
|
||||
|
||||
@classmethod
|
||||
def delete(cls, *args, **kwargs):
|
||||
# OVERRIDE DELETION
|
||||
# so that deleting a user will only disable it
|
||||
return cls.update(password="")
|
||||
# @classmethod
|
||||
# def delete(cls, *args, **kwargs):
|
||||
# return cls.delete()
|
||||
|
||||
@property
|
||||
def is_admin(self):
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class ConfigReader(QObject):
|
|||
|
||||
def read_config_file(self, config_path):
|
||||
config_path = str(config_path)
|
||||
config = ConfigParser(*self._args, **self._kwargs)
|
||||
config = ConfigParser(*self._args, **self._kwargs, allow_no_value=True,comment_prefixes="#",inline_comment_prefixes="#")
|
||||
read = config.read(config_path)
|
||||
if len(read) != 1 or config_path != read[0]:
|
||||
raise AssertionError(f"Config file {config_path} could not be read.")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from time import perf_counter, time
|
||||
|
||||
ref = time() - perf_counter()
|
||||
|
||||
pass
|
||||
|
||||
def timing():
|
||||
global ref
|
||||
|
|
|
|||
41
src/main.py
41
src/main.py
|
|
@ -68,7 +68,7 @@ try:
|
|||
from lib.helpers import ConfigReader
|
||||
from PyQt5.QtCore import QObject, QThread, pyqtSignal
|
||||
from PyQt5.QtWidgets import QApplication, QMessageBox
|
||||
from ui import About, Archive, Login, Main_Window, Test, Users_Management
|
||||
from ui import About, Archive, Login, Main_Window, Test, Users_Management, Recipe_Selection
|
||||
|
||||
if "--vision" in sys.argv:
|
||||
from components import GalaxyCamera, NeoPixels, UVCCamera, Vision, VisionSaver
|
||||
|
|
@ -166,23 +166,22 @@ try:
|
|||
Archive(hide_cloud_image="vision_saver" not in self().components)))
|
||||
if "--archive" in sys.argv:
|
||||
self.main_window.archive_a.trigger()
|
||||
self.main_window.about_a.triggered.connect(
|
||||
lambda checked, self=weakref.ref(self): self().main_window.open_dialog(About()))
|
||||
if "--about" in sys.argv:
|
||||
self.main_window.about_a.trigger()
|
||||
self.main_window.admin_m.menuAction().setVisible(
|
||||
False) # admin menu should not be visible before an admin logs in
|
||||
|
||||
# admin menu should not be visible before an admin logs in
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
|
||||
self.main_window.about_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(About()))
|
||||
self.main_window.quit_a.triggered.connect(quit_app)
|
||||
self.main_window.users_management_a.triggered.connect(
|
||||
lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Users_Management()))
|
||||
self.main_window.users_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Users_Management()))
|
||||
self.main_window.table_selection_a.triggered.connect(self.set_recipe_mode_table)
|
||||
self.main_window.barcode_selection_a.triggered.connect(self.set_recipe_mode_barcode)
|
||||
|
||||
if "--users-management" in sys.argv:
|
||||
self.main_window.users_management_a.trigger()
|
||||
# self.main_window.recipes_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Recipes_Management()))
|
||||
# if "--recipes-management" in sys.argv:
|
||||
# self.main_window.recipes_management_a.trigger()
|
||||
# self.main_window.steps_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Steps_Management()))
|
||||
# if "--steps-management" in sys.argv:
|
||||
# self.main_window.steps_management_a.trigger()
|
||||
|
||||
# CONFIG-SPECIFIC MENU ENTRY ACTIVATION
|
||||
if "tecna_t3" in self.components and (
|
||||
"--enable-saving-tecna-recipes" in sys.argv or self.config.get("tecna_t3", {}).get("saver",
|
||||
None) == "present"):
|
||||
|
|
@ -192,9 +191,8 @@ try:
|
|||
self.main_window.save_tecna_recipes_a.trigger()
|
||||
else:
|
||||
self.main_window.save_tecna_recipes_a.setVisible(False)
|
||||
self.main_window.barcode_selection_a.setVisible(self.config["hardware_config"]["barcode_recipe_selection"] == "present")
|
||||
|
||||
self.main_window.table_selection_a.triggered.connect(self.set_recipe_mode_table)
|
||||
self.main_window.barcode_selection_a.triggered.connect(self.set_recipe_mode_barcode)
|
||||
# OPEN LOGIN TAB
|
||||
self.open_login()
|
||||
# SHOW MAIN WINDOW
|
||||
|
|
@ -220,15 +218,22 @@ try:
|
|||
else:
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
# open test
|
||||
self.main_window.open_tab(Test(self.config, self.components))
|
||||
self.main_window.open_tab(Test(self.config, self.components,self))
|
||||
else:
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
|
||||
def logout(self):
|
||||
if type(self.main_window.centralWidget) is Test:
|
||||
self.main_window.centralWidget.change_recipe()
|
||||
Users.logout()
|
||||
self.main_window.admin_m.menuAction().setVisible(False)
|
||||
if type(self.main_window.centralWidget().centralWidget.widget) is Recipe_Selection:
|
||||
# LOGOUT IMMEDIATELY IF NOT TESTING
|
||||
self.open_login()
|
||||
else:
|
||||
if not self.main_window.centralWidget().autotesting:
|
||||
self.main_window.centralWidget().change_recipe() # STOP CURRENT TEST
|
||||
self.main_window.centralWidget().request_autotest("logout")
|
||||
else:
|
||||
# LOGOUT IMMEDIATELY IF AUTOTESTING
|
||||
self.open_login()
|
||||
|
||||
def set_recipe_mode_table(self):
|
||||
|
|
|
|||
35
src/scripts/csv_extract_LEAK.py
Normal file
35
src/scripts/csv_extract_LEAK.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import csv
|
||||
import json
|
||||
|
||||
file="STTEN5"
|
||||
with open(f"tmp/{file}.csv",) as csv_file:
|
||||
csv_reader = csv.reader(csv_file, delimiter=',')
|
||||
|
||||
with open(f'tmp/{file}_out.csv', 'w') as csv_out:
|
||||
|
||||
# create the csv writer
|
||||
writer = csv.writer(csv_out, lineterminator="\n")
|
||||
|
||||
line_count = 0
|
||||
for row in csv_reader:
|
||||
if line_count == 0:
|
||||
print(f'Column names are {", ".join(row)}')
|
||||
row.append("caduta")
|
||||
row.append("pressione")
|
||||
row.pop(1) # remove data column
|
||||
line_count += 1
|
||||
writer.writerow(row)
|
||||
else:
|
||||
data=json.loads(row[1])
|
||||
if "leak_1" in data.keys():
|
||||
leak=data["leak_1"]["0"]["results"]["data"]["""Running test: measured leak"""]
|
||||
press=data["leak_1"]["0"]["results"]["data"]["""Running test: filling pressure"""]
|
||||
leakstr=f'{leak:.3f}'
|
||||
pressstr = f'{press:.3f}'
|
||||
line_count += 1
|
||||
row.append(leakstr)
|
||||
row.append(pressstr)
|
||||
row.pop(1) # remove data column
|
||||
writer.writerow(row)
|
||||
|
||||
print(f'Processed {line_count} lines.')
|
||||
40
src/test/csv_import/Tabella_e_daily_p3.csv
Normal file
40
src/test/csv_import/Tabella_e_daily_p3.csv
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
codice_ricetta,Priorita ,descrizione,etichette_supplementari,Numero nastri (N),Numero sensori anello (SA),Numero sensori presenza (SP)
|
||||
5803223729,3,priorita 3,,,,
|
||||
5803223730,3,priorita 3,,,,
|
||||
5803223731,3,priorita 3,,,,
|
||||
5803223732,3,priorita 3,,,,
|
||||
5803223733,3,priorita 3,,,,
|
||||
5803223734,3,priorita 3,,,,
|
||||
5803223735,3,priorita 3,,,,
|
||||
5803223736,3,priorita 3,,,,
|
||||
5803223737,3,priorita 3,,,,
|
||||
5803223738,3,priorita 3,,,,
|
||||
5803223739,3,priorita 3,,,,
|
||||
5803223740,3,priorita 3,,,,
|
||||
5803223741,3,priorita 3,,,,
|
||||
5803223742,3,priorita 3,,,,
|
||||
5803223743,3,priorita 3,,,,
|
||||
5803223744,3,priorita 3,,,,
|
||||
5803223745,3,priorita 3,,,,
|
||||
5803223746,3,priorita 3,,,,
|
||||
5803223747,3,priorita 3,,,,
|
||||
5803223748,3,priorita 3,,,,
|
||||
5803223749,3,priorita 3,,,,
|
||||
5803223750,3,priorita 3,,,,
|
||||
5803223751,3,priorita 3,,,,
|
||||
5803223752,3,priorita 3,,,,
|
||||
5803223753,3,priorita 3,,,,
|
||||
5803120372,3,priorita 3,,,,
|
||||
5803120373,3,priorita 3,,,,
|
||||
5803120374,3,priorita 3,,,,
|
||||
5803120375,3,priorita 3,,,,
|
||||
5803101543,3,priorita 3,,,,
|
||||
5803101544,3,priorita 3,,,,
|
||||
5803101545,3,priorita 3,,,,
|
||||
5803101546,3,priorita 3,,,,
|
||||
5803101547,3,priorita 3,,,,
|
||||
5803223754,3,priorita 3,,,,
|
||||
5803223755,3,priorita 3,,,,
|
||||
5803120371,3,priorita 3,,,,
|
||||
5803228584,3,priorita 3,,,,
|
||||
5803228585,3,priorita 3,,,,
|
||||
|
46
src/test/rfid.py
Normal file
46
src/test/rfid.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import time
|
||||
import ndef
|
||||
import nfc
|
||||
from nfc.clf import RemoteTarget
|
||||
|
||||
clf = nfc.ContactlessFrontend()
|
||||
connected=False
|
||||
while True:
|
||||
try:
|
||||
if not connected:
|
||||
connected=clf.open('tty:USB0:pn532')
|
||||
if connected:
|
||||
target = clf.sense(RemoteTarget('106A'), RemoteTarget('106B'), RemoteTarget('212F'))
|
||||
if target is not None:
|
||||
tag = nfc.tag.activate(clf, target)
|
||||
if tag is not None:
|
||||
print(tag)
|
||||
if tag.ndef is not None:
|
||||
if not len(tag.ndef.records):
|
||||
print("EMPTY TAG - WRITING...")
|
||||
if not tag.ndef.is_writeable:
|
||||
print("This Tag is not writeable.")
|
||||
break
|
||||
else:
|
||||
tag.format()
|
||||
#tag.ndef.records = [ndef.TextRecord("Errecinque"),ndef.TextRecord("5812345678")]
|
||||
record=ndef.TextRecord("Errecinque,fixture,5812345678")
|
||||
tag.ndef.records = [record]
|
||||
if tag.ndef.has_changed:
|
||||
print("WRITE ERROR")
|
||||
else:
|
||||
print("WRITE OK")
|
||||
|
||||
for record in tag.ndef.records:
|
||||
print(record)
|
||||
else:
|
||||
print("ERROR NOT NDEF")
|
||||
else:
|
||||
print("NO TARGET")
|
||||
except Exception as e:
|
||||
print(f"EXCEPTION {e}")
|
||||
connected=False
|
||||
time.sleep(0.3)
|
||||
|
||||
print("EXITING")
|
||||
clf.close()
|
||||
|
|
@ -6,7 +6,7 @@ from datetime import datetime
|
|||
|
||||
from lib.db import Crud_DB
|
||||
from peewee import TextField
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QSize
|
||||
from PyQt5.QtWidgets import (QAbstractItemView, QComboBox, QDialog,
|
||||
QGridLayout, QHeaderView, QLineEdit, QMessageBox,
|
||||
QPlainTextEdit, QPushButton)
|
||||
|
|
@ -148,6 +148,7 @@ class Combo_Box_Cell_Widget(QComboBox, Cell):
|
|||
class External_Dialog_Cell_Widget(QPushButton, Cell):
|
||||
def __init__(self, action=None, readonly=True, autocomplete=None, field_name=None, field_alias=None, field=None, row_number=None, crud=None):
|
||||
self.dialog = QDialog()
|
||||
self.dialog.resize(QSize(800,800))
|
||||
self.editor = QPlainTextEdit()
|
||||
self.dialog.setLayout(QGridLayout())
|
||||
self.dialog.layout().setSpacing(0)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ class Leak_Step_Editor(Editor):
|
|||
"settling_pressure_max_percent": self.settling_pressure_max_percent_sb,
|
||||
# test
|
||||
"test_time": self.test_time_sb,
|
||||
"test_pressure_min_delta": self.test_pressure_min_delta_sb,
|
||||
"test_pressure_qneg": self.test_pressure_qneg_sb,
|
||||
"test_pressure": self.test_pressure_sb,
|
||||
"test_pressure_max_delta": self.test_pressure_max_delta_sb,
|
||||
"test_pressure_qpos": self.test_pressure_qpos_sb,
|
||||
# flush
|
||||
"flush_time": self.flush_time_sb,
|
||||
"flush_pressure": self.flush_pressure_sb,
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QSpinBox" name="test_pressure_min_delta_sb">
|
||||
<widget class="QSpinBox" name="test_pressure_qneg_sb">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
|
@ -238,7 +238,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QSpinBox" name="test_pressure_max_delta_sb">
|
||||
<widget class="QSpinBox" name="test_pressure_qpos_sb">
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>843</width>
|
||||
<height>28</height>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuAbout">
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>About</string>
|
||||
<string>Informazioni</string>
|
||||
</property>
|
||||
<addaction name="about_a"/>
|
||||
</widget>
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
</widget>
|
||||
<action name="about_a">
|
||||
<property name="text">
|
||||
<string>Powered by</string>
|
||||
<string>Contatti</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="users_management_a">
|
||||
|
|
|
|||
|
|
@ -128,8 +128,8 @@ class Recipe_Selection(Widget):
|
|||
self.export_b.setVisible(False)
|
||||
self.delete_all_b.setVisible(False)
|
||||
# TESTING
|
||||
if "--auto-select" in sys.argv or "--test" in sys.argv:
|
||||
recipe = "5802850925"
|
||||
if "--auto-select" in sys.argv:
|
||||
recipe = "000952054"
|
||||
cn = self.crud.select_index["name"]
|
||||
self.crud.db_tw.clearSelection()
|
||||
for rn in range(1, self.crud.db_tw.rowCount()):
|
||||
|
|
@ -214,9 +214,9 @@ class Recipe_Selection(Widget):
|
|||
"settling_pressure_min_percent": int(row.get("percentuale_minima_pressione_assestamento", defaults["percentuale_minima_pressione_assestamento"])),
|
||||
"settling_pressure_max_percent": int(row.get("percentuale_massima_pressione_assestamento", defaults["percentuale_massima_pressione_assestamento"])),
|
||||
"test_time": int(row.get("tempo_di_test", defaults["tempo_di_test"])),
|
||||
"test_pressure_min_delta": int(row.get("pressione_di_test_delta_minimo", defaults["pressione_di_test_delta_minimo"])),
|
||||
"test_pressure_qneg": int(row.get("pressione_di_test_delta_minimo", defaults["pressione_di_test_delta_minimo"])),
|
||||
"test_pressure": int(row.get("pressione_di_test", defaults["pressione_di_test"])),
|
||||
"test_pressure_max_delta": int(row.get("pressione_di_test_delta_massimo", defaults["pressione_di_test_delta_massimo"])),
|
||||
"test_pressure_qpos": int(row.get("pressione_di_test_delta_massimo", defaults["pressione_di_test_delta_massimo"])),
|
||||
"flush_time": int(row.get("tempo_svuotamento", defaults["tempo_svuotamento"])),
|
||||
"flush_pressure": int(row.get("pressione_svuotamento", defaults["pressione_svuotamento"])),
|
||||
"relay_config": int(row.get("config_elettrovalvole", defaults["config_elettrovalvole"]))
|
||||
|
|
@ -229,9 +229,9 @@ class Recipe_Selection(Widget):
|
|||
"settling_pressure_min_percent": int(row.get("percentuale_minima_pressione_assestamento_2", defaults["percentuale_minima_pressione_assestamento_2"])),
|
||||
"settling_pressure_max_percent": int(row.get("percentuale_massima_pressione_assestamento_2", defaults["percentuale_massima_pressione_assestamento_2"])),
|
||||
"test_time": int(row.get("tempo_di_test_2", defaults["tempo_di_test_2"])),
|
||||
"test_pressure_min_delta": int(row.get("pressione_di_test_delta_minimo_2", defaults["pressione_di_test_delta_minimo_2"])),
|
||||
"test_pressure_qneg": int(row.get("pressione_di_test_delta_minimo_2", defaults["pressione_di_test_delta_minimo_2"])),
|
||||
"test_pressure": int(row.get("pressione_di_test_2", defaults["pressione_di_test_2"])),
|
||||
"test_pressure_max_delta": int(row.get("pressione_di_test_delta_massimo_2", defaults["pressione_di_test_delta_massimo_2"])),
|
||||
"test_pressure_qpos": int(row.get("pressione_di_test_delta_massimo_2", defaults["pressione_di_test_delta_massimo_2"])),
|
||||
"flush_time": int(row.get("tempo_svuotamento_2", defaults["tempo_svuotamento_2"])),
|
||||
"flush_pressure": int(row.get("pressione_svuotamento_2", defaults["pressione_svuotamento_2"])),
|
||||
"relay_config": int(row.get("config_elettrovalvole_2", defaults["config_elettrovalvole_2"]))
|
||||
|
|
@ -434,9 +434,9 @@ class Recipe_Selection(Widget):
|
|||
"percentuale_minima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_min_percent"],
|
||||
"percentuale_massima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_max_percent"],
|
||||
"tempo_di_test": steps["leak_1"].spec["test_time"],
|
||||
"pressione_di_test_delta_minimo": steps["leak_1"].spec["test_pressure_min_delta"],
|
||||
"pressione_di_test_delta_minimo": steps["leak_1"].spec["test_pressure_qneg"],
|
||||
"pressione_di_test": steps["leak_1"].spec["test_pressure"],
|
||||
"pressione_di_test_delta_massimo": steps["leak_1"].spec["test_pressure_max_delta"],
|
||||
"pressione_di_test_delta_massimo": steps["leak_1"].spec["test_pressure_qpos"],
|
||||
"tempo_svuotamento": steps["leak_1"].spec["flush_time"],
|
||||
"pressione_svuotamento": steps["leak_1"].spec["flush_pressure"],
|
||||
"prova_tenuta_abilitata_2": "x" if recipe.spec["leak_2"] else "",
|
||||
|
|
@ -447,9 +447,9 @@ class Recipe_Selection(Widget):
|
|||
"percentuale_minima_pressione_assestamento_2": steps["leak_2"].spec["settling_pressure_min_percent"],
|
||||
"percentuale_massima_pressione_assestamento_2": steps["leak_2"].spec["settling_pressure_max_percent"],
|
||||
"tempo_di_test_2": steps["leak_2"].spec["test_time"],
|
||||
"pressione_di_test_delta_minimo_2": steps["leak_2"].spec["test_pressure_min_delta"],
|
||||
"pressione_di_test_delta_minimo_2": steps["leak_2"].spec["test_pressure_qneg"],
|
||||
"pressione_di_test_2": steps["leak_2"].spec["test_pressure"],
|
||||
"pressione_di_test_delta_massimo_2": steps["leak_2"].spec["test_pressure_max_delta"],
|
||||
"pressione_di_test_delta_massimo_2": steps["leak_2"].spec["test_pressure_qpos"],
|
||||
"tempo_svuotamento_2": steps["leak_2"].spec["flush_time"],
|
||||
"pressione_svuotamento_2": steps["leak_2"].spec["flush_pressure"],
|
||||
"test_visione_abilitato": recipe.spec["vision"],
|
||||
|
|
|
|||
1
src/ui/rfid_recipe_selection/__init__.py
Normal file
1
src/ui/rfid_recipe_selection/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from .rfid_recipe_selection import RFID_Recipe_Selection
|
||||
85
src/ui/rfid_recipe_selection/rfid_recipe_selection.py
Normal file
85
src/ui/rfid_recipe_selection/rfid_recipe_selection.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import sys
|
||||
|
||||
import peewee
|
||||
from PyQt5 import Qt
|
||||
|
||||
from lib.helpers import timing
|
||||
from PyQt5.QtCore import Qt, QTimer, QThread
|
||||
from PyQt5.QtGui import QKeySequence, QPixmap, QPalette, QColor
|
||||
from PyQt5.QtWidgets import QShortcut, QApplication
|
||||
from ui.widget import Widget
|
||||
from lib import db
|
||||
from lib.db.models import Recipes
|
||||
|
||||
class RFID(Widget):
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
self.parent=parent
|
||||
self.recipe_db_model=Recipes
|
||||
self.status_palettes = {
|
||||
True: QPalette(),
|
||||
"": QPalette(),
|
||||
"warning": QPalette(),
|
||||
False: QPalette(),
|
||||
None: QPalette(),
|
||||
}
|
||||
self.status_palettes[True].setColor(QPalette.Base, Qt.green)
|
||||
self.status_palettes[False].setColor(QPalette.Base, Qt.red)
|
||||
self.status_palettes["warning"].setColor(QPalette.Base, QColor(255, 165, 0))
|
||||
self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0))
|
||||
|
||||
self.delay_timer = QTimer()
|
||||
self.delay_timer.setSingleShot(True)
|
||||
self.delay_timer.timeout.connect(self.reset_display)
|
||||
|
||||
self.ok_timer = QTimer()
|
||||
self.ok_timer.setSingleShot(True)
|
||||
self.ok_timer.timeout.connect(self.set_recipe)
|
||||
|
||||
def start(self, recipe=None, step=None, pieces=None):
|
||||
|
||||
self.rfid_input_l.setPalette(self.status_palettes[None])
|
||||
self.rfid_input_l.setPlainText("")
|
||||
|
||||
def get(self, data=None, override=False):
|
||||
if not len(data):
|
||||
data = None
|
||||
if data is None:
|
||||
return
|
||||
else:
|
||||
lines = data
|
||||
if lines[0]=="ERRECINQUE RFID":
|
||||
# RECIPE CODE FOUND
|
||||
self.recipe=lines[1]
|
||||
self.rfid_input_l.setPalette(self.status_palettes[True])
|
||||
self.ok_timer.start(2000)
|
||||
|
||||
else:
|
||||
# RECIPE CODE NOT FOUND
|
||||
self.rfid_input_l.setPalette(self.status_palettes[False])
|
||||
self.instruction_text("FORMATO RFID DIMA NON VALIDO", "red")
|
||||
self.delay_timer.start(3000)
|
||||
|
||||
# LOOKUP RECIPE
|
||||
|
||||
def set_recipe(self):
|
||||
try:
|
||||
recipe = self.recipe_db_model.get_by_id(self.recipe)
|
||||
self.parent.set_recipe(recipe)
|
||||
except peewee.DoesNotExist:
|
||||
self.rfid_input_l.setPalette(self.status_palettes[False])
|
||||
self.instruction_text("RICETTA NON TROVATA","red")
|
||||
self.delay_timer.start(3000)
|
||||
|
||||
|
||||
def reset_display(self):
|
||||
self.rfid_input_l.setFocus()
|
||||
self.rfid_input_l.setPlainText("")
|
||||
self.rfid_input_l.setPalette(self.status_palettes[""])
|
||||
self.instruction_text("SCANSIONARE BARCODE SELEZIONE RICETTA")
|
||||
|
||||
def instruction_text(self,text,color=None):
|
||||
if getattr(self.parent.centralWidget, "set_text"):
|
||||
self.parent.centralWidget.set_text(text, color=color)
|
||||
|
||||
|
||||
95
src/ui/rfid_recipe_selection/rfid_recipe_selection.ui
Normal file
95
src/ui/rfid_recipe_selection/rfid_recipe_selection.ui
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Test_Connector</class>
|
||||
<widget class="QWidget" name="Test_Connector">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1445</width>
|
||||
<height>793</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Test Connector</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="2" column="0" alignment="Qt::AlignHCenter">
|
||||
<widget class="QLabel" name="state_l">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" alignment="Qt::AlignHCenter">
|
||||
<widget class="QPlainTextEdit" name="barcode_input_l">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="plainText">
|
||||
<string>123
|
||||
456
|
||||
abc</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" alignment="Qt::AlignHCenter">
|
||||
<widget class="QPushButton" name="recipe_selection_b">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TORNA ALLA TABELLA RICETTE</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -29,16 +29,15 @@ from ui.widget import Widget
|
|||
|
||||
|
||||
class Test(Widget):
|
||||
def __init__(self, config, components=None):
|
||||
def __init__(self, config, components=None,main_window=None):
|
||||
super().__init__()
|
||||
self.main_window=main_window
|
||||
self.config = config
|
||||
self.components = components
|
||||
# GET LOGGER
|
||||
self.log = logging.getLogger("Test")
|
||||
# SHOW MACHINE DESCRIPTION
|
||||
self.machine_description_l.setText(self.config.get("machine", {}).get("description", "N/A"))
|
||||
# SHOW USERNAME
|
||||
|
||||
# SHOW USERNAME
|
||||
session = Users.get_session()
|
||||
self.user_l.setText(session.username)
|
||||
|
|
@ -91,9 +90,9 @@ class Test(Widget):
|
|||
"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)),
|
||||
"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),
|
||||
"fail": Test_Assembly(img_path=self.select_step_img("fail"), text=u"CICLO INTERROTTO, PREMERE CONTINUA PER COMINCIARE UN NUOVO CICLO", widget=Test_Fail()),
|
||||
"fail": Test_Assembly(img_path=self.select_step_img("fail"), text=u"CICLO INTERROTTO, PREMERE CONTINUA PER COMINCIARE UN NUOVO CICLO", widget=Test_Fail(parent=self)),
|
||||
"leak_1": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces,parent=self)),
|
||||
"leak_2": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces)),
|
||||
"leak_2": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces,parent=self)),
|
||||
"instruction": Test_Assembly(img_path=None, text=u"ESEGUIRE LE OPERAZIONI DI MONTAGGIO INDICATE IN FIGURA", widget=Test_Instructions(components=self.components, recipe=self.recipe,bench_name=self.config.machine_id, step=self.step)),
|
||||
"print": Test_Assembly(img_path=self.select_step_img("print"), text=u"STAMPA ETICHETTA IN CORSO", widget=None),
|
||||
"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)),
|
||||
|
|
@ -113,7 +112,8 @@ class Test(Widget):
|
|||
self.autotesting_reason = None
|
||||
self.autotest_cycle_steps = None
|
||||
if "--no-autotest" not in sys.argv:
|
||||
self.autotest_period = 12 * 60 * 60 * 1000
|
||||
self.autotest_period = 8.5 * 60 * 60 * 1000 # 8.5 HOURS
|
||||
# self.autotest_period = 12 * 60 * 60 * 1000 # 12 HOURS
|
||||
if not self.config["autotest_done"]:
|
||||
self.request_autotest("init")
|
||||
else:
|
||||
|
|
@ -314,6 +314,8 @@ class Test(Widget):
|
|||
for i, step in enumerate(steps):
|
||||
if i in skip:
|
||||
continue
|
||||
if step.type == "vision":
|
||||
self.components["vision"].config_changed(vision_recipe=self.recipe.name)
|
||||
if step.type == "count":
|
||||
count_found = True
|
||||
if "warning_img" in step.spec:
|
||||
|
|
@ -349,6 +351,7 @@ class Test(Widget):
|
|||
self.cycle_steps = steps
|
||||
self.check_steps_dependencies(self.cycle_steps)
|
||||
leak_autotest_steps=[]
|
||||
# CONFIGURE LEAK AUTOTEST PARAMETERS
|
||||
if self.config["autotest_leak"]["enabled"]=="true":
|
||||
l_at_1=copy.deepcopy(self.config["autotest_leak"])
|
||||
l_at_1.pop("enabled")
|
||||
|
|
@ -357,6 +360,8 @@ class Test(Widget):
|
|||
l_at_2=copy.deepcopy(self.config["autotest_leak"])
|
||||
l_at_2.pop("enabled")
|
||||
l_at_2={a: float(x) for a, x in l_at_2.items()}
|
||||
l_at_2["test_pressure_qneg"]=l_at_2["test_pressure_tt_qneg"]
|
||||
l_at_2["test_pressure_qpos"]=l_at_2["test_pressure_tt_qpos"]
|
||||
l_at_2["autotest"]="ok_check"
|
||||
leak_autotest_steps=[Steps(type="leak_1",spec=l_at_1),Steps(type="leak_1",spec=l_at_2)]
|
||||
|
||||
|
|
@ -452,13 +457,32 @@ class Test(Widget):
|
|||
self.data[step_name] = {}
|
||||
if data is not None:
|
||||
data["step"] = model_to_dict(self.step)
|
||||
data["step"].pop("name",None)
|
||||
|
||||
# MAKE ARRAY ONLY IF MORE THAN ONE TEST OF SAME TYPE
|
||||
if len(self.data[step_name])>1:
|
||||
self.data[step_name][str(len(self.data[step_name]))] = data
|
||||
else:
|
||||
self.data[step_name] = data
|
||||
|
||||
self.data["overridden"] = self.data["overridden"] or data.get("overridden", False)
|
||||
self.data["ok"] = self.data["ok"] and data.get("ok", False)
|
||||
self.next()
|
||||
|
||||
def done(self, ok=True):
|
||||
self.log.info("cycle done")
|
||||
self.log.info("cycle done, saving data...")
|
||||
|
||||
#remove useless info
|
||||
self.data.get("recipe",{}).get("spec",{}).pop("steps",None)
|
||||
self.data.get("recipe",{}).get("spec",{}).pop("available_steps",None)
|
||||
for leak in ["leak_1","leak_2"]:
|
||||
if leak in self.data.keys():
|
||||
self.data[leak]["results"]={k:self.data[leak]["results"]["tecna_t3"][k] for k in ["Running test: filling pressure",
|
||||
"Running test: measured leak",
|
||||
"Running test: pressure at the end of settling",
|
||||
"Running test: result"]
|
||||
|
||||
}
|
||||
if "vision" in self.data:
|
||||
vision_test_1 = self.data.get("vision", {}).get("0", {})
|
||||
out_paths = self.components["vision_saver"].save(
|
||||
|
|
@ -471,6 +495,9 @@ class Test(Widget):
|
|||
for vision in self.data.get("vision", {}).values():
|
||||
vision.pop("frame", None)
|
||||
vision.pop("render", None)
|
||||
vision.pop("detections", None)
|
||||
if "results" in vision.keys():
|
||||
vision["results"].pop("results", None)
|
||||
if self.autotesting:
|
||||
self.data["autotest"] = True
|
||||
self.data["autotest_reason"] = self.autotesting_reason
|
||||
|
|
@ -483,6 +510,11 @@ class Test(Widget):
|
|||
self.pieces["ok"] += 1
|
||||
else:
|
||||
self.pieces["ko"] += 1
|
||||
else:
|
||||
if self.autotesting_reason == "logout":
|
||||
if ok:
|
||||
self.main_window.show_login()
|
||||
|
||||
return archived
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -503,21 +535,19 @@ class Test(Widget):
|
|||
self.log.info("cycle printed already compiled label")
|
||||
# LABEL PRINT
|
||||
recipe = archived.test_data.get("recipe", {})
|
||||
leak_test_1 = archived.test_data.get("leak_1", {}).get("0", {})
|
||||
leak_test_1 = archived.test_data.get("leak_1", {})
|
||||
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_data = leak_test_1_results.get("data", {})
|
||||
leak_test_2 = archived.test_data.get("leak_2", {}).get("0", {})
|
||||
leak_test_2 = archived.test_data.get("leak_2", {})
|
||||
leak_test_2_step = leak_test_2.get("step", {})
|
||||
leak_test_2_step_spec = leak_test_2_step.get("spec", {})
|
||||
leak_test_2_results = leak_test_2.get("results", {})
|
||||
leak_test_2_results_data = leak_test_2_results.get("data", {})
|
||||
|
||||
psetminp_a = leak_test_1_step_spec.get("test_pressure", 0) * (100+leak_test_1_step_spec.get("test_pressure_min_delta", 0)/100)
|
||||
psetmaxp_a = leak_test_1_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_1_step_spec.get("test_pressure_max_delta", 0)/100)
|
||||
psetminp2_a = leak_test_2_step_spec.get("settling_pressure_min_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_min_delta", 0)/100)
|
||||
psetmaxp2_a = leak_test_2_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_max_delta", 0)/100)
|
||||
psetminp_a = leak_test_1_step_spec.get("test_pressure", 0) * (100+leak_test_1_step_spec.get("test_pressure_qneg", 0)/100)
|
||||
psetmaxp_a = leak_test_1_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_1_step_spec.get("test_pressure_qpos", 0)/100)
|
||||
psetminp2_a = leak_test_2_step_spec.get("settling_pressure_min_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_qneg", 0)/100)
|
||||
psetmaxp2_a = leak_test_2_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_qpos", 0)/100)
|
||||
|
||||
printer_fields = self.step.spec
|
||||
context = {
|
||||
|
|
@ -525,6 +555,7 @@ class Test(Widget):
|
|||
"RECIPE": self.labellify(recipe.get("name", "-")),
|
||||
"CLIENT": self.labellify(recipe.get("client", "-")),
|
||||
"PART": self.labellify(recipe.get("part_number", "-")),
|
||||
"DESCRIPTION": self.labellify(recipe.get("description", "-")),
|
||||
# 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", "-")),
|
||||
|
|
@ -544,24 +575,22 @@ class Test(Widget):
|
|||
"PSETMAXP2_A": self.labellify(psetmaxp2_a),
|
||||
"TTEST": self.labellify(leak_test_1_step_spec.get("test_time", "-")),
|
||||
"TTEST2": self.labellify(leak_test_2_step_spec.get("test_time", "-")),
|
||||
"PMIN": self.labellify(leak_test_1_step_spec.get("test_pressure_min_delta", "-")),
|
||||
"PMIN2": self.labellify(leak_test_2_step_spec.get("test_pressure_min_delta", "-")),
|
||||
"PMIN": self.labellify(leak_test_1_step_spec.get("test_pressure_qneg", "-")),
|
||||
"PMIN2": self.labellify(leak_test_2_step_spec.get("test_pressure_qneg", "-")),
|
||||
"PTEST": self.labellify(leak_test_1_step_spec.get("test_pressure", "-")),
|
||||
"PTEST2": self.labellify(leak_test_2_step_spec.get("test_pressure", "-")),
|
||||
"PMAX": self.labellify(leak_test_1_step_spec.get("test_pressure_max_delta", "-")),
|
||||
"PMAX": self.labellify(leak_test_1_step_spec.get("test_pressure_qpos", "-")),
|
||||
"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", "-")),
|
||||
"RESPSET2": self.labellify(leak_test_2_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", "-")),
|
||||
"RESLEAK2": self.labellify(leak_test_2_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", "-")),
|
||||
"RESPFILL": self.labellify(leak_test_1_results.get("Running test: filling pressure", "-")),
|
||||
"RESPFILL2": self.labellify(leak_test_2_results.get("Running test: filling pressure", "-")),
|
||||
"RESPSET": self.labellify(leak_test_1_results.get("Running test: pressure at the end of settling", "-")),
|
||||
"RESPSET2": self.labellify(leak_test_2_results.get("Running test: pressure at the end of settling", "-")),
|
||||
"RESLEAK": self.labellify(leak_test_1_results.get("Running test: measured leak", "-")),
|
||||
"RESLEAK2": self.labellify(leak_test_2_results.get("Running test: measured leak", "-")),
|
||||
"RESRES": self.labellify(leak_test_1_results.get("Running test: result", "-")),
|
||||
"RESRES2": self.labellify(leak_test_2_results.get("Running test: result", "-")),
|
||||
# SERIAL DEFINITION
|
||||
"SN": str(archived.id),
|
||||
"SN4": f"{archived.id:0>4}",
|
||||
|
|
@ -597,6 +626,13 @@ class Test(Widget):
|
|||
|
||||
# PRINT MAIN PRODUCT LABEL
|
||||
compiled_label = self.components["label_printer"].print_label(label, context=context)
|
||||
# if recipe.get("part_number", "-") == "5802814210 R.3":
|
||||
# num_labels=2
|
||||
# else:
|
||||
# num_labels=1
|
||||
#
|
||||
# for i in range(num_labels):
|
||||
# compiled_label = self.components["label_printer"].print_label(label, context=context)
|
||||
self.log.info(f"Main label printed: {context!r}")
|
||||
return compiled_label
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>842</width>
|
||||
<height>118</height>
|
||||
<width>1252</width>
|
||||
<height>146</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
|
@ -52,52 +52,7 @@
|
|||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="1" column="0" rowspan="2">
|
||||
<widget class="QPushButton" name="change_recipe_b">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CAMBIA DISEGNO</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" rowspan="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="4" rowspan="2">
|
||||
<item row="1" column="5" rowspan="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
|
@ -110,71 +65,6 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QLabel" name="pieces_count_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>12345</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6" rowspan="2">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PEZZI FATTI</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" rowspan="2">
|
||||
<widget class="QLabel" name="time_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>12345
|
||||
567</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2">
|
||||
<widget class="QPushButton" name="cancel_b">
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -201,14 +91,38 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="1" column="7" rowspan="2">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="11">
|
||||
<widget class="QLabel" name="machine_description_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLabel" name="pieces_count_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
|
|
@ -217,25 +131,14 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N. DISEGNO:</string>
|
||||
<string>12345</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="7">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OPERATORE:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<item row="1" column="9">
|
||||
<widget class="QLabel" name="recipe_l">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
|
|
@ -268,7 +171,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="2" column="8">
|
||||
<widget class="QLabel" name="user_l">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
|
|
@ -277,11 +180,66 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
<string>OPERATORE:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9" rowspan="2">
|
||||
<item row="1" column="4" rowspan="2">
|
||||
<widget class="QLabel" name="time_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>12345
|
||||
567</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N. DISEGNO:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PEZZI FATTI</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="10" rowspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
|
@ -297,11 +255,24 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="10">
|
||||
<widget class="QLabel" name="machine_description_l">
|
||||
<item row="1" column="3" rowspan="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="9">
|
||||
<widget class="QLabel" name="user_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
|
|
@ -309,6 +280,69 @@
|
|||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" rowspan="2">
|
||||
<widget class="QPushButton" name="change_recipe_b">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CAMBIA DISEGNO</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="time_l_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ULTIMO AUTOTEST:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="autotests_l">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DD/MM/YY HH:MM</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -90,4 +90,4 @@ class Test_Connector(Test_Test):
|
|||
return barcode is not None and len(barcode)
|
||||
|
||||
def set_focus(self):
|
||||
self.barcodes_le.setFocus()
|
||||
self.connector_le.setFocus()
|
||||
|
|
|
|||
|
|
@ -10,14 +10,24 @@ from ui.test_test import Test_Test
|
|||
|
||||
|
||||
class Test_Fail(Test_Test):
|
||||
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False):
|
||||
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False,parent=None):
|
||||
super().__init__(components=components, recipe=recipe, step=step, pieces=pieces, run_once=run_once, reset_on_start=reset_on_start, enable_override=enable_override)
|
||||
self.continue_b.clicked.connect(lambda checked, self=weakref.ref(self): self().ok.emit(None))
|
||||
self.parent=parent
|
||||
self.discard_timer=QTimer()
|
||||
self.discard_timer.timeout.connect(self.wait_discard)
|
||||
|
||||
def start(self, recipe=None, step=None, pieces=None):
|
||||
show = super().start(recipe=recipe, step=step, pieces=pieces)
|
||||
if show is False:
|
||||
return show
|
||||
if "discard_box" in self.parent.config["hardware_config"].keys():
|
||||
if self.parent_assembly_widget is not None :
|
||||
self.continue_b.setVisible(False)
|
||||
self.discard_timer.start(100)
|
||||
self.parent_assembly_widget().set_text(text="TEST KO - INSERIRE IL PEZZO COLLAUDATO NEL CONTENITORE DI SEGREGAZIONE SCARTI")
|
||||
self.io_connection=self.components["digital_io"].out.connect(self.wait_discard)
|
||||
|
||||
self.visualize()
|
||||
# TESTING
|
||||
if "--test" in sys.argv:
|
||||
|
|
@ -25,11 +35,21 @@ class Test_Fail(Test_Test):
|
|||
self.test_timer.setSingleShot(True)
|
||||
self.test_timer.timeout.connect(self.continue_b.click)
|
||||
self.test_timer.start(500)
|
||||
# /TESTING
|
||||
return show
|
||||
|
||||
# def stop(self):
|
||||
# super().stop()
|
||||
def stop(self):
|
||||
if "discard_box" in self.parent.config["hardware_config"].keys():
|
||||
self.disconnect(self.io_connection)
|
||||
super().stop()
|
||||
|
||||
def wait_discard(self,data=None):
|
||||
if data is not None:
|
||||
if len(data[0]["digital_io"]) == 0:
|
||||
return
|
||||
else:
|
||||
sensor_index = int(self.parent.config["digital_io"]["discard_idx"])
|
||||
byte_idx = int(sensor_index / 8)
|
||||
bit_idx = sensor_index % 8
|
||||
if data[0]["digital_io"][byte_idx][bit_idx]:
|
||||
self.ok.emit(None)
|
||||
|
||||
# def reset(self):
|
||||
# super().reset()
|
||||
|
|
|
|||
|
|
@ -2,23 +2,32 @@ import sys
|
|||
import time
|
||||
import weakref
|
||||
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from PyQt5.QtWidgets import QMessageBox, QDialog
|
||||
|
||||
from ui import Dialog
|
||||
from ui.test_test import Test_Test
|
||||
from components.Automation.BDaq import ErrorCode
|
||||
|
||||
class Test_Leak(Test_Test):
|
||||
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False,parent=None):
|
||||
super().__init__(components=components, recipe=recipe, step=step, pieces=pieces, run_once=run_once, reset_on_start=reset_on_start, enable_override=enable_override)
|
||||
self.parent=parent
|
||||
self.step=step
|
||||
self.start_b.clicked.connect(self.start_test)
|
||||
self.stop_b.clicked.connect(lambda checked, self=weakref.ref(self): self().components["tecna_t3"].stop_test())
|
||||
self.parent=parent
|
||||
self.show_instruction_b.setVisible("show_instructions" in self.parent.config["hardware_config"].keys())
|
||||
self.show_instruction_b.clicked.connect(self.show_instruction)
|
||||
|
||||
def show_instruction(self):
|
||||
dialog=Dialog()
|
||||
dialog.setCentralWidget(self.parent.cycle_available_steps["instruction"])
|
||||
dialog.show()
|
||||
|
||||
def start_test(self):
|
||||
# print extra labels
|
||||
if self.step.type == "leak_1":
|
||||
self.parent.print_extra_labels()
|
||||
|
||||
self.components["tecna_t3"].start_test()
|
||||
|
||||
def start(self, recipe=None, step=None, pieces=None):
|
||||
|
|
@ -32,6 +41,17 @@ class Test_Leak(Test_Test):
|
|||
if show is False:
|
||||
return show
|
||||
|
||||
if "leak_2" in [s.type for s in self.parent.cycle_steps]:
|
||||
if self.step.type=="leak_1":
|
||||
self.test_num_l.setText("1/2")
|
||||
else:
|
||||
self.test_num_l.setText("2/2")
|
||||
else:
|
||||
self.test_num_l.setText("1/1")
|
||||
|
||||
self.recipe_pressure_l.setText(f"{self.step.spec['test_pressure']}")
|
||||
self.leak_min_l.setText(f"{self.step.spec['test_pressure_qneg']}")
|
||||
self.leak_max_l.setText(f"{self.step.spec['test_pressure_qpos']}")
|
||||
# setup test loop
|
||||
self.components["tecna_t3"].write_recipe(self.recipe, self.step)
|
||||
self.get_connection = self.components["tecna_t3"].out.connect(self.get)
|
||||
|
|
@ -102,7 +122,7 @@ class Test_Leak(Test_Test):
|
|||
if step == "ok_check":
|
||||
ok = type(result) is str and "passed" in result.lower() # AUTOTEST - NO LEAK
|
||||
elif step == "ko_check":
|
||||
ok = type(result) is str and "failed" in result.lower() # AUTOTEST - LEAK
|
||||
ok = type(result) is str and "passed" in result.lower() # AUTOTEST - LEAK
|
||||
else:
|
||||
ok = type(result) is str and "passed" in result.lower() # NORMAL TEST
|
||||
|
||||
|
|
@ -112,25 +132,30 @@ class Test_Leak(Test_Test):
|
|||
ret = self.components["digital_io"].set_bit_verify(0, 1, 0)
|
||||
|
||||
else:
|
||||
result = None
|
||||
#result = None
|
||||
ok = None
|
||||
|
||||
results={"ok":ok}
|
||||
results.update(data)
|
||||
super().get([{
|
||||
"time": data.get("time", None),
|
||||
"results": {
|
||||
"ok": ok,
|
||||
"result": result,
|
||||
"data": data["tecna_t3"],
|
||||
},
|
||||
"results": results
|
||||
#"results": {
|
||||
#"ok": ok,
|
||||
#"result": result,
|
||||
#"data": data["tecna_t3"],
|
||||
#},
|
||||
}], override=override, fail=ok is False)
|
||||
|
||||
def visualize(self, data=None):
|
||||
if data is None:
|
||||
data = {}
|
||||
d = data.get("results", {}).get("data", {})
|
||||
d = data.get("results", {}).get("tecna_t3", {})
|
||||
for k, l in {
|
||||
"Running test: active phase": self.test_phase_l,
|
||||
"Real time test pressure output": self.circuit_pressure_l,
|
||||
"Real time differential pressure output": self.leak_l,
|
||||
#"Real time differential pressure output": self.leak_l,
|
||||
"Running test: measured leak": self.leak_l,
|
||||
"Real time pressure line regulator": self.regulated_pressure_l,
|
||||
# "Active alarm flags": self._l,
|
||||
"Running test: test type": self.test_type_l,
|
||||
|
|
@ -156,6 +181,9 @@ class Test_Leak(Test_Test):
|
|||
if self.parent_assembly_widget is not None:
|
||||
self.parent_assembly_widget().set_text(text="COLLEGARE GLI ATTACCHI PNEUMATICI E PREMERE START PER INIZIARE LA PROVA TENUTA")
|
||||
self.start_b.setEnabled(True)
|
||||
self.start_b.setDefault(True)
|
||||
self.start_b.setFocus()
|
||||
|
||||
self.stop_b.setEnabled(False)
|
||||
else:
|
||||
if self.step is not None:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,7 @@
|
|||
import sys
|
||||
import time
|
||||
import weakref
|
||||
from datetime import datetime
|
||||
|
||||
from lib.helpers import timing
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
|
||||
|
|
@ -119,6 +121,7 @@ class Test_Test(Widget):
|
|||
self.last = None
|
||||
|
||||
def get(self, data=None, override=False, fail=False, preserve_counter=False, skip_delay=False):
|
||||
cur_timing = timing()
|
||||
if self.done: # avoid proccessing if completed
|
||||
return
|
||||
if data is None:
|
||||
|
|
@ -129,18 +132,19 @@ class Test_Test(Widget):
|
|||
data = self.last if self.last is not None else {}
|
||||
else:
|
||||
data = data[-data_usable.index(True) - 1]
|
||||
if data.get("time", None) is None:
|
||||
data["time"] = timing()
|
||||
data["time"] = datetime.now().strftime("%H:%M:%S")
|
||||
if fail:
|
||||
result_ok = False
|
||||
elif override:
|
||||
result_ok = True
|
||||
else:
|
||||
result_ok = data.get("results", {}).get("ok", None)
|
||||
duration=cur_timing - self.start_time
|
||||
data.pop("step",None)
|
||||
self.last = {
|
||||
**data,
|
||||
"overridden": override,
|
||||
"duration": timing() - self.start_time,
|
||||
"duration": float(f"{duration:.2f}"),
|
||||
"ok": result_ok,
|
||||
}
|
||||
if fail:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user