Merge remote-tracking branch 'origin/master'

# Conflicts:
#	runme_custom.sh
This commit is contained in:
Guglielmi 2023-06-13 10:32:23 +02:00
commit bb01c51eeb
54 changed files with 2824 additions and 1147 deletions

Binary file not shown.

View File

@ -1,4 +1,4 @@
SIZE 37.5 mm, 130 mm SIZE 27.5 mm, 50 mm
GAP 3 mm, 0 mm GAP 3 mm, 0 mm
SPEED 2 SPEED 2
DENSITY 7 DENSITY 7
@ -10,10 +10,9 @@ SET CUTTER OFF
SET PARTIAL_CUTTER OFF SET PARTIAL_CUTTER OFF
SET TEAR ON SET TEAR ON
CLS 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 CODEPAGE 1252
TEXT 261,377,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}{SN5}" TEXT 212,357,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}{SN5}"
DMATRIX 116,175,184,184,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}" DMATRIX 82,129,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
DMATRIX 116,78,184,184,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}" DMATRIX 82,28,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
BOX 13,16,287,401,3
PRINT 1,1 PRINT 1,1

View File

@ -12,7 +12,7 @@ SET TEAR ON
CLS CLS
DMATRIX 82,230,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}" DMATRIX 82,230,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
CODEPAGE 1252 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,129,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
DMATRIX 82,28,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 PRINT 1,1

View File

@ -18,25 +18,25 @@
^XZ ^XZ
^XA ^XA
^MMT ^MMT
^PW320 ^PW496
^LL1119 ^LL1559
^LS0 ^LS0
^FT33,86^A0N,45,46^FH\^CI28^FDERRECINQUE^FS^CI27 ^FT61,119^A0N,67,68^FH\^CI28^FDERRECINQUE^FS^CI27
^BY2,3,56^FT44,310^BCN,,N,N ^BY2,3,83^FT77,430^BCN,,N,N
^FH\^FD>:{PART}^FS ^FH\^FD>:{PART}^FS
^FT15,347^A0N,31,30^FH\^CI28^FDPart number:^FS^CI27 ^FT34,482^A0N,46,46^FH\^CI28^FDPart number:^FS^CI27
^FT15,427^A0N,31,30^FH\^CI28^FD{PART}^FS^CI27 ^FT34,595^A0N,46,46^FH\^CI28^FD{PART}^FS^CI27
^FT17,136^A0N,17,18^FH\^CI28^FDVia Meucci 31/A - 10079 Mappano(TO)^FS^CI27 ^FT37,172^A0N,25,25^FH\^CI28^FDVia Meucci 31/A - 10079 Mappano(TO)^FS^CI27
^FT53,193^A0N,39,38^FH\^CI28^FDFPT^FS^CI27 ^FT91,256^A0N,58,56^FH\^CI28^FDFPT^FS^CI27
^FT53,235^A0N,39,38^FH\^CI28^FDLEAK TEST^FS^CI27 ^FT91,312^A0N,58,56^FH\^CI28^FDLEAK TEST^FS^CI27
^FT15,387^A0N,31,30^FH\^CI28^FD{DESCRIPTION}^FS^CI27 ^FT34,530^A0N,46,46^FH\^CI28^FD{DESCRIPTION}^FS^CI27
^FT15,740^A0N,31,30^FH\^CI28^FDSequential number:^FS^CI27 ^FT34,1243^A0N,46,46^FH\^CI28^FDSequential number:^FS^CI27
^FT15,779^A0N,31,30^FH\^CI28^FD{SN5}^FS^CI27 ^FT34,1291^A0N,46,46^FH\^CI28^FD{SN5}^FS^CI27
^FT15,856^A0N,17,18^FH\^CI28^FD{DD}/{MM}/{YY}^FS^CI27 ^FT34,1361^A0N,33,33^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
^FT161,856^A0N,17,18^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27 ^FT250,1361^A0N,33,33^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
^FT17,1081^A0N,31,30^FH\^CI28^FDESITO:^FS^CI27 ^FT37,1487^A0N,46,46^FH\^CI28^FDCHECK:^FS^CI27
^FT143,1081^A0N,31,30^FH\^CI28^FDCONFORME^FS^CI27 ^FT223,1487^A0N,46,46^FH\^CI28^FDCONFORME^FS^CI27
^FT15,934^A0N,25,25^FH\^CI28^FDOperatore^FS^CI27 ^FT34,1427^A0N,38,38^FH\^CI28^FDOperatore^FS^CI27
^FT15,967^A0N,25,25^FH\^CI28^FD{OPERATOR}^FS^CI27 ^FT223,1427^A0N,38,38^FH\^CI28^FD{OPERATOR}^FS^CI27
^PQ1,0,1,Y ^PQ1,0,1,Y
^XZ ^XZ

View 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

View File

@ -162,9 +162,9 @@ settling_time: 5
settling_pressure_min_percent: 5 settling_pressure_min_percent: 5
settling_pressure_max_percent: 5 settling_pressure_max_percent: 5
test_time: 10 test_time: 10
test_pressure_min_delta: 5 test_pressure_qneg: 5
test_pressure: 9000 test_pressure: 9000
test_pressure_max_delta: 5 test_pressure_qpos: 5
flush_time: 1 flush_time: 1
flush_pressure: 100 flush_pressure: 100

View File

@ -2,6 +2,8 @@
ST-TEN-1: st-ten-1 ST-TEN-1: st-ten-1
ST-TEN-2: st-ten-2 ST-TEN-2: st-ten-2
stten3: st-ten-3 stten3: st-ten-3
stten4: st-ten-4 ST-TEN-4: st-ten-4
st-ten-5: st-ten-5 st-ten-5: st-ten-5
st-ten-6: st-ten-6 st-ten-6: st-ten-6
st-ten-7: st-ten-7
st-ten-8: st-ten-8

View File

@ -10,7 +10,7 @@ neo_pixels: present
remote_api: absent remote_api: absent
tecna_t3: present tecna_t3: present
vision_saver: present vision_saver: present
vision: absent vision: present
screwdriver: present screwdriver: present
[tecna_t3] [tecna_t3]
@ -29,3 +29,67 @@ description_field: descrizione
[label_printer] [label_printer]
platform: windows platform: windows
printer: zd420 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

View File

@ -39,3 +39,19 @@ pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1 tempo_svuotamento: 1
pressione_svuotamento: 100 pressione_svuotamento: 100
config_elettrovalvole: 0 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

View File

@ -10,6 +10,7 @@ remote_api: absent
tecna_t3: present tecna_t3: present
digital_io: present digital_io: present
barcode_recipe_selection: present barcode_recipe_selection: present
show_instructions: yes
[tecna_t3] [tecna_t3]
port: COM4 port: COM4
@ -90,9 +91,9 @@ settling_time: 10
settling_pressure_min_percent: 5 settling_pressure_min_percent: 5
settling_pressure_max_percent: 5 settling_pressure_max_percent: 5
test_time: 10 test_time: 10
test_pressure_min_delta: 10 test_pressure_qneg: 10
test_pressure: 5000 test_pressure: 5000
test_pressure_max_delta: 5 test_pressure_qpos: 5
flush_time: 1 flush_time: 1
flush_pressure: 100 flush_pressure: 100
relay_config: 1 relay_config: 1

View File

@ -3,8 +3,7 @@ description = ST-TEN-6 DOPPIA PROVA PRESSIONE 6/20 BAR
[hardware_config] [hardware_config]
archive_synchronizer: present archive_synchronizer: present
; galaxy_camera: present uvc_camera: absent
uvc_camera: present
label_printer: present label_printer: present
neo_pixels: present neo_pixels: present
remote_api: absent remote_api: absent
@ -28,6 +27,7 @@ printer: zd421
[digital_io] [digital_io]
id: USB-5860,BID#0 id: USB-5860,BID#0
[recipe] [recipe]
recipe_name_field: codice_ricetta recipe_name_field: codice_ricetta
part_number_field: codice_prodotto part_number_field: codice_prodotto
@ -38,8 +38,8 @@ description_field: descrizione
dimensione_lotto_abilitata: dimensione_lotto_abilitata:
tempo_pre_riempimento: 0 tempo_pre_riempimento: 0
pressione_pre_riempimento: 1000 pressione_pre_riempimento: 1000
tempo_riempimento: 15 tempo_riempimento: 10
tempo_assestamento: 15 tempo_assestamento: 10
tempo_di_test: 10 tempo_di_test: 10
percentuale_minima_pressione_assestamento: 5 percentuale_minima_pressione_assestamento: 5
percentuale_massima_pressione_assestamento: 5 percentuale_massima_pressione_assestamento: 5
@ -52,8 +52,8 @@ config_elettrovalvole: 1
prova_tenuta_abilitata_2: prova_tenuta_abilitata_2:
tempo_pre_riempimento_2: 0 tempo_pre_riempimento_2: 0
pressione_pre_riempimento_2: 1000 pressione_pre_riempimento_2: 1000
tempo_riempimento_2: 20 tempo_riempimento_2: 10
tempo_assestamento_2: 20 tempo_assestamento_2: 10
tempo_di_test_2: 10 tempo_di_test_2: 10
percentuale_minima_pressione_assestamento_2: 5 percentuale_minima_pressione_assestamento_2: 5
percentuale_massima_pressione_assestamento_2: 5 percentuale_massima_pressione_assestamento_2: 5
@ -69,14 +69,16 @@ modello_etichetta: EtichettaR5_Montaggio_1prova.prn
enabled: true enabled: true
pre_filling_time: 0 pre_filling_time: 0
pre_filling_pressure: 1000 pre_filling_pressure: 1000
filling_time: 15 filling_time: 10
settling_time: 10 settling_time: 10
settling_pressure_min_percent: 5 settling_pressure_min_percent: 5
settling_pressure_max_percent: 5 settling_pressure_max_percent: 5
test_pressure: 7000
test_time: 10 test_time: 10
test_pressure_min_delta: 35 test_pressure_qpos: 5 #Q+ Upper test leak limit
test_pressure: 15000 test_pressure_qneg: 15 #Q- Lower test leak limit
test_pressure_max_delta: 5 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_time: 1
flush_pressure: 100 flush_pressure: 100
relay_config: 1 relay_config: 1

View 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

View 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

View File

@ -0,0 +1,10 @@
item {
id: 1
name: 'ok'
color: '0x55AA55'
}
item {
id: 2
name: 'ko'
color: '0xff0000'
}

View File

@ -1,10 +1,10 @@
item { item {
id: 1 id: 1
name: 'hs-ok' name: 'ok'
color: '0x55AA55' color: '0x55AA55'
} }
item { item {
id: 2 id: 2
name: 'hs-ko' name: 'ko'
color: '0xff0000' color: '0xff0000'
} }

View File

@ -0,0 +1,10 @@
item {
id: 1
name: 'hs-ok'
color: '0x55AA55'
}
item {
id: 2
name: 'hs-ko'
color: '0xff0000'
}

View 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

View File

@ -3,6 +3,8 @@
[general] [general]
name: TERMORESTRINGENTE name: TERMORESTRINGENTE
instruction: CONTROLLARE PRESENZA TERMORESTRINGENTE instruction: CONTROLLARE PRESENZA TERMORESTRINGENTE
neural_network: hs5-20000
type: global
# POINTS FORMAT: # POINTS FORMAT:
# point_name: point_center point_size fill_color border_color border_thickness shape # 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

View File

@ -2,7 +2,13 @@
:: RUN FROM POWERSHELL W/ADMIN RIGHTS: :: RUN FROM POWERSHELL W/ADMIN RIGHTS:
:: Set-ExecutionPolicy Unrestricted -Scope CurrentUser :: Set-ExecutionPolicy Unrestricted -Scope CurrentUser
pip install -r src/requirements.txt
mkdir tmp
cd tmp cd tmp
:: Advantech XNAVI
Invoke-WebRequest -uri "https://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-2BZC0F1" -usebasicparsing -outfile xnavi.zip
:: GXIPY :: 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

View File

@ -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
View 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
View 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])

View File

@ -205,15 +205,16 @@ class TecnaMarpossProvasetT3(ModbusComponent):
# READ INFO # READ INFO
info = {r: self.read(r) for r in [ info = {r: self.read(r) for r in [
"Real time test pressure output", "Real time test pressure output",
"Real time differential pressure output",
"Real time pressure line regulator", "Real time pressure line regulator",
"Active alarm flags", #"Real time differential pressure output",
"Active test program number", #"Active alarm flags",
#"Active test program number",
"Running test: active phase", "Running test: active phase",
"Running test: test type", "Running test: test type",
"Running test: measured leak",
"Running test: sequence index", "Running test: sequence index",
"Digital inputs status (mask)", "Digital inputs status (mask)",
# "Digital outputs status (mask)", "Digital outputs status (mask)",
]} ]}
if self.model == "t3p": if self.model == "t3p":
pass pass
@ -222,9 +223,12 @@ class TecnaMarpossProvasetT3(ModbusComponent):
"Active not severe alarm flags", "Active not severe alarm flags",
]}) ]})
else: 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": if info["Running test: active phase"] == "FINE TEST": # "END TEST, WAITING THE START OF A NEW TEST":
info.update(self.get_test_results()) 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)) self.log.debug(str(info))
super()._get([info]) super()._get([info])
@ -251,13 +255,13 @@ class TecnaMarpossProvasetT3(ModbusComponent):
def get_test_results(self): def get_test_results(self):
self.log.info("getting test results") self.log.info("getting test results")
return {r: self.read(r) for r in [ return {r: self.read(r) for r in [
"Running test: phase backwards time", #"Running test: phase backwards time",
"Running test: filling pressure", "Running test: filling pressure",
"Running test: pressure at the end of settling", "Running test: pressure at the end of settling",
"Running test: burst pressure", #"Running test: burst pressure",
"Running test: measured leak", "Running test: measured leak",
"Running test: calculated leak flow rate", #"Running test: calculated leak flow rate",
"Running test: calculate RVP%", #"Running test: calculate RVP%",
"Running test: result", "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 # **{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, "Print options": 0b0000000000000000 | self.saver_label_count << 12 | self.saver_print_on_fail << 8 | self.saver_label_template,
"Test type": "Leak Test", "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"], "T0 - Pre-filling time": step.spec["pre_filling_time"],
"P0 - Pre-filling pressure": step.spec["pre_filling_pressure"], "P0 - Pre-filling pressure": step.spec["pre_filling_pressure"],
"T1 - Filling time": step.spec["filling_time"], "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- - Min pressure tolerance %": step.spec["settling_pressure_min_percent"],
"PR+ - Max pressure tolerance % (P+)": step.spec["settling_pressure_max_percent"], "PR+ - Max pressure tolerance % (P+)": step.spec["settling_pressure_max_percent"],
"T3 - Measure time": step.spec["test_time"], "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"], "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"], "FST - Discharge time": step.spec["flush_time"],
"FSL - Discharge limit": step.spec["flush_pressure"], "FSL - Discharge limit": step.spec["flush_pressure"],
} }

View File

@ -80,7 +80,7 @@ registers = {
"Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 1507, }], "Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 1507, }],
"Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }], "Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }],
"Running test: result": [46 - 1, {"dt": "16bit_uint", "decoding": { "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", 2: "BURST TEST PASSED WITH BURST",
3: "BURST TEST PASSED WITHOUT BURST", 3: "BURST TEST PASSED WITHOUT BURST",
4: "APERTURE TEST PASSED", 4: "APERTURE TEST PASSED",

View File

@ -59,7 +59,7 @@ registers = {
"Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 24, }], "Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 24, }],
"Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }], "Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }],
"Running test: result": [46 - 1, {"dt": "16bit_uint", "decoding": { "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", 2: "BURST TEST PASSED WITH BURST",
3: "BURST TEST PASSED WITHOUT BURST", 3: "BURST TEST PASSED WITHOUT BURST",
4: "APERTURE TEST PASSED", 4: "APERTURE TEST PASSED",

View File

@ -57,7 +57,7 @@ else:
class Vision(Component): 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) status_signal = pyqtSignal(object)
loading_model_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) super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
self.lock = QMutex() self.lock = QMutex()
self.simulate = "--sim-vision" in sys.argv self.simulate = "--sim-vision" in sys.argv
self.vision_config = None
def start(self): def start(self):
self.model = None self.model = None
@ -96,7 +97,7 @@ class Vision(Component):
self.render_consumer.out.connect(self.process_render_consumed) self.render_consumer.out.connect(self.process_render_consumed)
super().start() super().start()
def config_changed(self): def config_changed(self,vision_recipe=None):
# OBJECT DETECTION # OBJECT DETECTION
self.detection_threshold = float(self.config[self.name].get("detection_threshold", 0.5)) self.detection_threshold = float(self.config[self.name].get("detection_threshold", 0.5))
# recipe # recipe
@ -104,7 +105,8 @@ class Vision(Component):
self.labels = None self.labels = None
# LOAD RECIPE # LOAD RECIPE
self.recipes_dir = Path(self.config[self.name].get("recipes_dir", "./config/vision/recipes")) 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 = QFileSystemWatcher([])
self.recipe_watcher.fileChanged.connect(self._set_recipe) self.recipe_watcher.fileChanged.connect(self._set_recipe)
# LOAD MODEL # LOAD MODEL
@ -119,9 +121,11 @@ class Vision(Component):
if "--no-tflite" in sys.argv: if "--no-tflite" in sys.argv:
self.allowed_modes.pop("edgetpu", None) self.allowed_modes.pop("edgetpu", None)
self.allowed_modes.pop("tflite", 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 # 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) 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) 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) 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) return pow((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2, 1 / 2)
def clear_recipe(self): def clear_recipe(self):
self.recipe = None self.recipe_name = None
self.markers = {} self.markers = {}
self.zones = {} self.zones = {}
self.labels = {} self.labels = {}
@ -170,6 +174,7 @@ class Vision(Component):
if len(read) != 1 or self.recipe_path not in read: if len(read) != 1 or self.recipe_path not in read:
raise AssertionError("Recipe could not be read.") raise AssertionError("Recipe could not be read.")
os.path.splitext(os.path.basename(read[0]))[0] 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.markers = self.parse_markers(config._sections.get("markers", None))
self.zones = self.parse_zones(config._sections.get("zones", None)) self.zones = self.parse_zones(config._sections.get("zones", None))
self.labels = self.parse_labels(config._sections.get("labels", 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.log.exception(f"Error reading {self.recipe_path!r}:")
self.clear_recipe() self.clear_recipe()
self.status_signal.emit({ self.status_signal.emit({
"recipe": self.recipe, "recipe": self.recipe_name,
"markers": self.markers, "markers": self.markers,
"zones": self.zones, "zones": self.zones,
"labels": self.labels, "labels": self.labels,
@ -189,8 +194,8 @@ class Vision(Component):
if recipe is None: if recipe is None:
self.clear_recipe() self.clear_recipe()
else: else:
self.recipe = recipe self.recipe_name = recipe.split(".")[0]
self._set_recipe(self.recipes_dir / str(recipe)) self._set_recipe(self.recipes_dir / f"{self.recipe_name}.ini")
def parse_markers(self, config=None): def parse_markers(self, config=None):
if config is None: if config is None:
@ -434,11 +439,104 @@ class Vision(Component):
parsed_detections.append(detection) parsed_detections.append(detection)
return parsed_detections 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): def detections_to_items(self, detections):
# DRAW DETECTIONS # DRAW DETECTIONS
if detections is not None and len(detections): if detections is not None and len(detections):
style = { style = {
"border_thickness": 25, "border_thickness": 5,
"fill_color": QColor("#00000000"), "fill_color": QColor("#00000000"),
"shape": "rect", "shape": "rect",
"convert_negative_placement": False, "convert_negative_placement": False,
@ -460,7 +558,7 @@ class Vision(Component):
# MATCH DETECTIONS WITH RECIPE # MATCH DETECTIONS WITH RECIPE
results = dict.fromkeys(self.zones) results = dict.fromkeys(self.zones)
for detection in detections: 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 # filtering out those that do not contain the detection
min_distance = sys.maxsize min_distance = sys.maxsize
closest_zone = None closest_zone = None
@ -586,7 +684,7 @@ class Vision(Component):
**style, **style,
"border_color": Qt.green if item["ok"] else Qt.red, "border_color": Qt.green if item["ok"] else Qt.red,
} }
return items return items
else: else:
return {} return {}
@ -744,7 +842,11 @@ class Vision(Component):
# VISION_CONSUMER TASK # VISION_CONSUMER TASK
if consumable is None: if consumable is None:
return return
detections = self.check_features(consumable["frame"]) 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) results = self.process_detections(detections)
return {"detections": detections, "results": results} return {"detections": detections, "results": results}

View File

@ -60,8 +60,8 @@ def init_db():
# "connector": {"connector": row["connector"]}, # "connector": {"connector": row["connector"]},
# "barcodes": {"serial": ""}, # "barcodes": {"serial": ""},
# "resistance": {"scale": 500, "expected": float(row["resistance_expected"]), "tolerance": float(row["resistance_tolerance"])}, # "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_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_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_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
# "vision": {"recipe": "termorestringente_923578.ini"}, # "vision": {"recipe": "termorestringente_923578.ini"},
# "print": {"template": "EtichettaR5.prn", }, # "print": {"template": "EtichettaR5.prn", },
# }.items(): # }.items():

View File

@ -10,7 +10,7 @@ from .users import Users
class Archive(BaseModel): class Archive(BaseModel):
id = AutoField(primary_key=True, unique=True, null=False) id = AutoField(primary_key=True, unique=True, null=False)
time = DateTimeField(unique=True, null=False, default=datetime.now) time = DateTimeField(unique=True, null=False, default=datetime.now())
user = ForeignKeyField(Users, Users.username, null=False) user = ForeignKeyField(Users, Users.username, null=False)
result = BooleanField(null=False) result = BooleanField(null=False)
overridden = BooleanField(null=False) overridden = BooleanField(null=False)
@ -22,7 +22,11 @@ class Archive(BaseModel):
@classmethod @classmethod
@db.atomic() @db.atomic()
def archive(cls, test_data, result, overridden): 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( return cls.create(
time=time,
user=Users.get_session().user, user=Users.get_session().user,
result=result, result=result,
overridden=overridden, overridden=overridden,

View File

@ -136,11 +136,9 @@ class Users(BaseModel):
def delete_by_username(cls, username): def delete_by_username(cls, username):
cls.update(password="").where(cls.username == username).execute() cls.update(password="").where(cls.username == username).execute()
@classmethod # @classmethod
def delete(cls, *args, **kwargs): # def delete(cls, *args, **kwargs):
# OVERRIDE DELETION # return cls.delete()
# so that deleting a user will only disable it
return cls.update(password="")
@property @property
def is_admin(self): def is_admin(self):

View File

@ -48,7 +48,7 @@ class ConfigReader(QObject):
def read_config_file(self, config_path): def read_config_file(self, config_path):
config_path = str(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) read = config.read(config_path)
if len(read) != 1 or config_path != read[0]: if len(read) != 1 or config_path != read[0]:
raise AssertionError(f"Config file {config_path} could not be read.") raise AssertionError(f"Config file {config_path} could not be read.")

View File

@ -1,7 +1,7 @@
from time import perf_counter, time from time import perf_counter, time
ref = time() - perf_counter() ref = time() - perf_counter()
pass
def timing(): def timing():
global ref global ref

View File

@ -68,7 +68,7 @@ try:
from lib.helpers import ConfigReader from lib.helpers import ConfigReader
from PyQt5.QtCore import QObject, QThread, pyqtSignal from PyQt5.QtCore import QObject, QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMessageBox 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: if "--vision" in sys.argv:
from components import GalaxyCamera, NeoPixels, UVCCamera, Vision, VisionSaver from components import GalaxyCamera, NeoPixels, UVCCamera, Vision, VisionSaver
@ -166,23 +166,22 @@ try:
Archive(hide_cloud_image="vision_saver" not in self().components))) Archive(hide_cloud_image="vision_saver" not in self().components)))
if "--archive" in sys.argv: if "--archive" in sys.argv:
self.main_window.archive_a.trigger() 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: if "--about" in sys.argv:
self.main_window.about_a.trigger() 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.quit_a.triggered.connect(quit_app)
self.main_window.users_management_a.triggered.connect( self.main_window.users_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Users_Management()))
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: if "--users-management" in sys.argv:
self.main_window.users_management_a.trigger() 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: # CONFIG-SPECIFIC MENU ENTRY ACTIVATION
# 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()
if "tecna_t3" in self.components and ( if "tecna_t3" in self.components and (
"--enable-saving-tecna-recipes" in sys.argv or self.config.get("tecna_t3", {}).get("saver", "--enable-saving-tecna-recipes" in sys.argv or self.config.get("tecna_t3", {}).get("saver",
None) == "present"): None) == "present"):
@ -192,9 +191,8 @@ try:
self.main_window.save_tecna_recipes_a.trigger() self.main_window.save_tecna_recipes_a.trigger()
else: else:
self.main_window.save_tecna_recipes_a.setVisible(False) 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 # OPEN LOGIN TAB
self.open_login() self.open_login()
# SHOW MAIN WINDOW # SHOW MAIN WINDOW
@ -220,16 +218,23 @@ try:
else: else:
self.main_window.admin_m.menuAction().setVisible(False) self.main_window.admin_m.menuAction().setVisible(False)
# open test # open test
self.main_window.open_tab(Test(self.config, self.components)) self.main_window.open_tab(Test(self.config, self.components,self))
else: else:
self.main_window.admin_m.menuAction().setVisible(False) self.main_window.admin_m.menuAction().setVisible(False)
def logout(self): def logout(self):
if type(self.main_window.centralWidget) is Test:
self.main_window.centralWidget.change_recipe()
Users.logout() Users.logout()
self.main_window.admin_m.menuAction().setVisible(False) self.main_window.admin_m.menuAction().setVisible(False)
self.open_login() 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): def set_recipe_mode_table(self):
self.main_window.centralWidget().set_recipe_mode_table() self.main_window.centralWidget().set_recipe_mode_table()

View 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.')

View 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,,,,
1 codice_ricetta Priorita  descrizione etichette_supplementari Numero nastri (N) Numero sensori anello (SA) Numero sensori presenza (SP)
2 5803223729 3 priorita  3
3 5803223730 3 priorita  3
4 5803223731 3 priorita  3
5 5803223732 3 priorita  3
6 5803223733 3 priorita  3
7 5803223734 3 priorita  3
8 5803223735 3 priorita  3
9 5803223736 3 priorita  3
10 5803223737 3 priorita  3
11 5803223738 3 priorita  3
12 5803223739 3 priorita  3
13 5803223740 3 priorita  3
14 5803223741 3 priorita  3
15 5803223742 3 priorita  3
16 5803223743 3 priorita  3
17 5803223744 3 priorita  3
18 5803223745 3 priorita  3
19 5803223746 3 priorita  3
20 5803223747 3 priorita  3
21 5803223748 3 priorita  3
22 5803223749 3 priorita  3
23 5803223750 3 priorita  3
24 5803223751 3 priorita  3
25 5803223752 3 priorita  3
26 5803223753 3 priorita  3
27 5803120372 3 priorita  3
28 5803120373 3 priorita  3
29 5803120374 3 priorita  3
30 5803120375 3 priorita  3
31 5803101543 3 priorita  3
32 5803101544 3 priorita  3
33 5803101545 3 priorita  3
34 5803101546 3 priorita  3
35 5803101547 3 priorita  3
36 5803223754 3 priorita  3
37 5803223755 3 priorita  3
38 5803120371 3 priorita  3
39 5803228584 3 priorita  3
40 5803228585 3 priorita  3

46
src/test/rfid.py Normal file
View 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()

View File

@ -6,7 +6,7 @@ from datetime import datetime
from lib.db import Crud_DB from lib.db import Crud_DB
from peewee import TextField 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, from PyQt5.QtWidgets import (QAbstractItemView, QComboBox, QDialog,
QGridLayout, QHeaderView, QLineEdit, QMessageBox, QGridLayout, QHeaderView, QLineEdit, QMessageBox,
QPlainTextEdit, QPushButton) QPlainTextEdit, QPushButton)
@ -148,6 +148,7 @@ class Combo_Box_Cell_Widget(QComboBox, Cell):
class External_Dialog_Cell_Widget(QPushButton, 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): 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 = QDialog()
self.dialog.resize(QSize(800,800))
self.editor = QPlainTextEdit() self.editor = QPlainTextEdit()
self.dialog.setLayout(QGridLayout()) self.dialog.setLayout(QGridLayout())
self.dialog.layout().setSpacing(0) self.dialog.layout().setSpacing(0)

View File

@ -15,9 +15,9 @@ class Leak_Step_Editor(Editor):
"settling_pressure_max_percent": self.settling_pressure_max_percent_sb, "settling_pressure_max_percent": self.settling_pressure_max_percent_sb,
# test # test
"test_time": self.test_time_sb, "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": self.test_pressure_sb,
"test_pressure_max_delta": self.test_pressure_max_delta_sb, "test_pressure_qpos": self.test_pressure_qpos_sb,
# flush # flush
"flush_time": self.flush_time_sb, "flush_time": self.flush_time_sb,
"flush_pressure": self.flush_pressure_sb, "flush_pressure": self.flush_pressure_sb,

View File

@ -221,7 +221,7 @@
</widget> </widget>
</item> </item>
<item row="4" column="2"> <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"> <property name="minimum">
<number>0</number> <number>0</number>
</property> </property>
@ -238,7 +238,7 @@
</widget> </widget>
</item> </item>
<item row="6" column="2"> <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"> <property name="maximum">
<number>9999</number> <number>9999</number>
</property> </property>

View File

@ -25,7 +25,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>843</width> <width>843</width>
<height>28</height> <height>31</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuAbout"> <widget class="QMenu" name="menuAbout">
@ -35,7 +35,7 @@
</font> </font>
</property> </property>
<property name="title"> <property name="title">
<string>About</string> <string>Informazioni</string>
</property> </property>
<addaction name="about_a"/> <addaction name="about_a"/>
</widget> </widget>
@ -72,7 +72,7 @@
</widget> </widget>
<action name="about_a"> <action name="about_a">
<property name="text"> <property name="text">
<string>Powered by</string> <string>Contatti</string>
</property> </property>
</action> </action>
<action name="users_management_a"> <action name="users_management_a">

View File

@ -128,8 +128,8 @@ class Recipe_Selection(Widget):
self.export_b.setVisible(False) self.export_b.setVisible(False)
self.delete_all_b.setVisible(False) self.delete_all_b.setVisible(False)
# TESTING # TESTING
if "--auto-select" in sys.argv or "--test" in sys.argv: if "--auto-select" in sys.argv:
recipe = "5802850925" recipe = "000952054"
cn = self.crud.select_index["name"] cn = self.crud.select_index["name"]
self.crud.db_tw.clearSelection() self.crud.db_tw.clearSelection()
for rn in range(1, self.crud.db_tw.rowCount()): 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_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"])), "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_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": 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_time": int(row.get("tempo_svuotamento", defaults["tempo_svuotamento"])),
"flush_pressure": int(row.get("pressione_svuotamento", defaults["pressione_svuotamento"])), "flush_pressure": int(row.get("pressione_svuotamento", defaults["pressione_svuotamento"])),
"relay_config": int(row.get("config_elettrovalvole", defaults["config_elettrovalvole"])) "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_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"])), "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_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": 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_time": int(row.get("tempo_svuotamento_2", defaults["tempo_svuotamento_2"])),
"flush_pressure": int(row.get("pressione_svuotamento_2", defaults["pressione_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"])) "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_minima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_min_percent"],
"percentuale_massima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_max_percent"], "percentuale_massima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_max_percent"],
"tempo_di_test": steps["leak_1"].spec["test_time"], "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": 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"], "tempo_svuotamento": steps["leak_1"].spec["flush_time"],
"pressione_svuotamento": steps["leak_1"].spec["flush_pressure"], "pressione_svuotamento": steps["leak_1"].spec["flush_pressure"],
"prova_tenuta_abilitata_2": "x" if recipe.spec["leak_2"] else "", "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_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"], "percentuale_massima_pressione_assestamento_2": steps["leak_2"].spec["settling_pressure_max_percent"],
"tempo_di_test_2": steps["leak_2"].spec["test_time"], "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_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"], "tempo_svuotamento_2": steps["leak_2"].spec["flush_time"],
"pressione_svuotamento_2": steps["leak_2"].spec["flush_pressure"], "pressione_svuotamento_2": steps["leak_2"].spec["flush_pressure"],
"test_visione_abilitato": recipe.spec["vision"], "test_visione_abilitato": recipe.spec["vision"],

View File

@ -0,0 +1 @@
from .rfid_recipe_selection import RFID_Recipe_Selection

View 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)

View 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>

View File

@ -29,16 +29,15 @@ from ui.widget import Widget
class Test(Widget): class Test(Widget):
def __init__(self, config, components=None): def __init__(self, config, components=None,main_window=None):
super().__init__() super().__init__()
self.main_window=main_window
self.config = config self.config = config
self.components = components self.components = components
# GET LOGGER # GET LOGGER
self.log = logging.getLogger("Test") self.log = logging.getLogger("Test")
# SHOW MACHINE DESCRIPTION # SHOW MACHINE DESCRIPTION
self.machine_description_l.setText(self.config.get("machine", {}).get("description", "N/A")) self.machine_description_l.setText(self.config.get("machine", {}).get("description", "N/A"))
# SHOW USERNAME
# SHOW USERNAME # SHOW USERNAME
session = Users.get_session() session = Users.get_session()
self.user_l.setText(session.username) 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)), "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), "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), "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_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)), "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), "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)), "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.autotesting_reason = None
self.autotest_cycle_steps = None self.autotest_cycle_steps = None
if "--no-autotest" not in sys.argv: 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"]: if not self.config["autotest_done"]:
self.request_autotest("init") self.request_autotest("init")
else: else:
@ -314,6 +314,8 @@ class Test(Widget):
for i, step in enumerate(steps): for i, step in enumerate(steps):
if i in skip: if i in skip:
continue continue
if step.type == "vision":
self.components["vision"].config_changed(vision_recipe=self.recipe.name)
if step.type == "count": if step.type == "count":
count_found = True count_found = True
if "warning_img" in step.spec: if "warning_img" in step.spec:
@ -349,6 +351,7 @@ class Test(Widget):
self.cycle_steps = steps self.cycle_steps = steps
self.check_steps_dependencies(self.cycle_steps) self.check_steps_dependencies(self.cycle_steps)
leak_autotest_steps=[] leak_autotest_steps=[]
# CONFIGURE LEAK AUTOTEST PARAMETERS
if self.config["autotest_leak"]["enabled"]=="true": if self.config["autotest_leak"]["enabled"]=="true":
l_at_1=copy.deepcopy(self.config["autotest_leak"]) l_at_1=copy.deepcopy(self.config["autotest_leak"])
l_at_1.pop("enabled") l_at_1.pop("enabled")
@ -357,6 +360,8 @@ class Test(Widget):
l_at_2=copy.deepcopy(self.config["autotest_leak"]) l_at_2=copy.deepcopy(self.config["autotest_leak"])
l_at_2.pop("enabled") l_at_2.pop("enabled")
l_at_2={a: float(x) for a, x in l_at_2.items()} 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" 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)] 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] = {} self.data[step_name] = {}
if data is not None: if data is not None:
data["step"] = model_to_dict(self.step) data["step"] = model_to_dict(self.step)
self.data[step_name][str(len(self.data[step_name]))] = data 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["overridden"] = self.data["overridden"] or data.get("overridden", False)
self.data["ok"] = self.data["ok"] and data.get("ok", False) self.data["ok"] = self.data["ok"] and data.get("ok", False)
self.next() self.next()
def done(self, ok=True): 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: if "vision" in self.data:
vision_test_1 = self.data.get("vision", {}).get("0", {}) vision_test_1 = self.data.get("vision", {}).get("0", {})
out_paths = self.components["vision_saver"].save( out_paths = self.components["vision_saver"].save(
@ -471,6 +495,9 @@ class Test(Widget):
for vision in self.data.get("vision", {}).values(): for vision in self.data.get("vision", {}).values():
vision.pop("frame", None) vision.pop("frame", None)
vision.pop("render", None) vision.pop("render", None)
vision.pop("detections", None)
if "results" in vision.keys():
vision["results"].pop("results", None)
if self.autotesting: if self.autotesting:
self.data["autotest"] = True self.data["autotest"] = True
self.data["autotest_reason"] = self.autotesting_reason self.data["autotest_reason"] = self.autotesting_reason
@ -483,6 +510,11 @@ class Test(Widget):
self.pieces["ok"] += 1 self.pieces["ok"] += 1
else: else:
self.pieces["ko"] += 1 self.pieces["ko"] += 1
else:
if self.autotesting_reason == "logout":
if ok:
self.main_window.show_login()
return archived return archived
@staticmethod @staticmethod
@ -503,21 +535,19 @@ class Test(Widget):
self.log.info("cycle printed already compiled label") self.log.info("cycle printed already compiled label")
# LABEL PRINT # LABEL PRINT
recipe = archived.test_data.get("recipe", {}) 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 = leak_test_1.get("step", {})
leak_test_1_step_spec = leak_test_1_step.get("spec", {}) leak_test_1_step_spec = leak_test_1_step.get("spec", {})
leak_test_1_results = leak_test_1.get("results", {}) leak_test_1_results = leak_test_1.get("results", {})
leak_test_1_results_data = leak_test_1_results.get("data", {}) leak_test_2 = archived.test_data.get("leak_2", {})
leak_test_2 = archived.test_data.get("leak_2", {}).get("0", {})
leak_test_2_step = leak_test_2.get("step", {}) leak_test_2_step = leak_test_2.get("step", {})
leak_test_2_step_spec = leak_test_2_step.get("spec", {}) leak_test_2_step_spec = leak_test_2_step.get("spec", {})
leak_test_2_results = leak_test_2.get("results", {}) 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) 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_max_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_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_min_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_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_max_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_qpos", 0)/100)
printer_fields = self.step.spec printer_fields = self.step.spec
context = { context = {
@ -525,6 +555,7 @@ class Test(Widget):
"RECIPE": self.labellify(recipe.get("name", "-")), "RECIPE": self.labellify(recipe.get("name", "-")),
"CLIENT": self.labellify(recipe.get("client", "-")), "CLIENT": self.labellify(recipe.get("client", "-")),
"PART": self.labellify(recipe.get("part_number", "-")), "PART": self.labellify(recipe.get("part_number", "-")),
"DESCRIPTION": self.labellify(recipe.get("description", "-")),
# STEP SPEC # STEP SPEC
"TPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_time", "-")), "TPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_time", "-")),
"PPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_pressure", "-")), "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), "PSETMAXP2_A": self.labellify(psetmaxp2_a),
"TTEST": self.labellify(leak_test_1_step_spec.get("test_time", "-")), "TTEST": self.labellify(leak_test_1_step_spec.get("test_time", "-")),
"TTEST2": self.labellify(leak_test_2_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", "-")), "PMIN": self.labellify(leak_test_1_step_spec.get("test_pressure_qneg", "-")),
"PMIN2": self.labellify(leak_test_2_step_spec.get("test_pressure_min_delta", "-")), "PMIN2": self.labellify(leak_test_2_step_spec.get("test_pressure_qneg", "-")),
"PTEST": self.labellify(leak_test_1_step_spec.get("test_pressure", "-")), "PTEST": self.labellify(leak_test_1_step_spec.get("test_pressure", "-")),
"PTEST2": self.labellify(leak_test_2_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", "-")), "TFLUSH": self.labellify(leak_test_1_step_spec.get("flush_time", "-")),
"PFLUSH": self.labellify(leak_test_1_step_spec.get("flush_pressure", "-")), "PFLUSH": self.labellify(leak_test_1_step_spec.get("flush_pressure", "-")),
# ACTUAL TESTED VALUES # ACTUAL TESTED VALUES
"RESTPB": self.labellify(leak_test_1_results_data.get("Running test: phase backwards time", "-")), "RESPFILL": self.labellify(leak_test_1_results.get("Running test: filling pressure", "-")),
"RESPFILL": self.labellify(leak_test_1_results_data.get("Running test: filling pressure", "-")), "RESPFILL2": self.labellify(leak_test_2_results.get("Running test: filling pressure", "-")),
"RESPSET": self.labellify(leak_test_1_results_data.get("Running test: pressure at the end of settling", "-")), "RESPSET": self.labellify(leak_test_1_results.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", "-")), "RESPSET2": self.labellify(leak_test_2_results.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.get("Running test: measured leak", "-")),
"RESLEAK": self.labellify(leak_test_1_results_data.get("Running test: measured leak", "-")), "RESLEAK2": self.labellify(leak_test_2_results.get("Running test: measured leak", "-")),
"RESLEAK2": self.labellify(leak_test_2_results_data.get("Running test: measured leak", "-")), "RESRES": self.labellify(leak_test_1_results.get("Running test: result", "-")),
"RESFLOW": self.labellify(leak_test_1_results_data.get("Running test: calculated leak flow rate", "-")), "RESRES2": self.labellify(leak_test_2_results.get("Running test: result", "-")),
"RESRVP": self.labellify(leak_test_1_results_data.get("Running test: calculate RVP%", "-")),
"RESRES": self.labellify(leak_test_1_results_data.get("Running test: result", "-")),
# SERIAL DEFINITION # SERIAL DEFINITION
"SN": str(archived.id), "SN": str(archived.id),
"SN4": f"{archived.id:0>4}", "SN4": f"{archived.id:0>4}",
@ -597,6 +626,13 @@ class Test(Widget):
# PRINT MAIN PRODUCT LABEL # PRINT MAIN PRODUCT LABEL
compiled_label = self.components["label_printer"].print_label(label, context=context) 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}") self.log.info(f"Main label printed: {context!r}")
return compiled_label return compiled_label

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>842</width> <width>1252</width>
<height>118</height> <height>146</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -52,52 +52,7 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>3</number> <number>3</number>
</property> </property>
<item row="1" column="0" rowspan="2"> <item row="1" column="5" 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">
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -110,71 +65,6 @@
</property> </property>
</spacer> </spacer>
</item> </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"> <item row="1" column="1" rowspan="2">
<widget class="QPushButton" name="cancel_b"> <widget class="QPushButton" name="cancel_b">
<property name="sizePolicy"> <property name="sizePolicy">
@ -201,14 +91,38 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="7"> <item row="1" column="7" rowspan="2">
<widget class="QLabel" name="label_7"> <spacer name="horizontalSpacer_4">
<property name="sizePolicy"> <property name="orientation">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred"> <enum>Qt::Horizontal</enum>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </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"> <property name="font">
<font> <font>
<pointsize>12</pointsize> <pointsize>12</pointsize>
@ -217,25 +131,14 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>N. DISEGNO:</string> <string>12345</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="7"> <item row="1" column="9">
<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">
<widget class="QLabel" name="recipe_l"> <widget class="QLabel" name="recipe_l">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred"> <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
@ -268,7 +171,7 @@
</widget> </widget>
</item> </item>
<item row="2" column="8"> <item row="2" column="8">
<widget class="QLabel" name="user_l"> <widget class="QLabel" name="label_6">
<property name="font"> <property name="font">
<font> <font>
<pointsize>12</pointsize> <pointsize>12</pointsize>
@ -277,11 +180,66 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>-</string> <string>OPERATORE:</string>
</property> </property>
</widget> </widget>
</item> </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"> <spacer name="horizontalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -297,11 +255,24 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="0" colspan="10"> <item row="1" column="3" rowspan="2">
<widget class="QLabel" name="machine_description_l"> <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"> <property name="font">
<font> <font>
<pointsize>16</pointsize> <pointsize>12</pointsize>
<weight>75</weight> <weight>75</weight>
<bold>true</bold> <bold>true</bold>
</font> </font>
@ -309,6 +280,69 @@
<property name="text"> <property name="text">
<string>-</string> <string>-</string>
</property> </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"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>

View File

@ -90,4 +90,4 @@ class Test_Connector(Test_Test):
return barcode is not None and len(barcode) return barcode is not None and len(barcode)
def set_focus(self): def set_focus(self):
self.barcodes_le.setFocus() self.connector_le.setFocus()

View File

@ -10,14 +10,24 @@ from ui.test_test import Test_Test
class Test_Fail(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) 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.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): def start(self, recipe=None, step=None, pieces=None):
show = super().start(recipe=recipe, step=step, pieces=pieces) show = super().start(recipe=recipe, step=step, pieces=pieces)
if show is False: if show is False:
return show 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() self.visualize()
# TESTING # TESTING
if "--test" in sys.argv: if "--test" in sys.argv:
@ -25,11 +35,21 @@ class Test_Fail(Test_Test):
self.test_timer.setSingleShot(True) self.test_timer.setSingleShot(True)
self.test_timer.timeout.connect(self.continue_b.click) self.test_timer.timeout.connect(self.continue_b.click)
self.test_timer.start(500) self.test_timer.start(500)
# /TESTING
return show return show
# def stop(self): def stop(self):
# super().stop() 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()

View File

@ -2,24 +2,33 @@ import sys
import time import time
import weakref 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 ui.test_test import Test_Test
from components.Automation.BDaq import ErrorCode from components.Automation.BDaq import ErrorCode
class Test_Leak(Test_Test): 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): 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) 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.step=step
self.start_b.clicked.connect(self.start_test) 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.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): def start_test(self):
# print extra labels # print extra labels
if self.step.type == "leak_1": if self.step.type == "leak_1":
self.parent.print_extra_labels() self.parent.print_extra_labels()
self.components["tecna_t3"].start_test()
self.components["tecna_t3"].start_test()
def start(self, recipe=None, step=None, pieces=None): def start(self, recipe=None, step=None, pieces=None):
# TESTING # TESTING
@ -32,6 +41,17 @@ class Test_Leak(Test_Test):
if show is False: if show is False:
return show 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 # setup test loop
self.components["tecna_t3"].write_recipe(self.recipe, self.step) self.components["tecna_t3"].write_recipe(self.recipe, self.step)
self.get_connection = self.components["tecna_t3"].out.connect(self.get) self.get_connection = self.components["tecna_t3"].out.connect(self.get)
@ -102,7 +122,7 @@ class Test_Leak(Test_Test):
if step == "ok_check": if step == "ok_check":
ok = type(result) is str and "passed" in result.lower() # AUTOTEST - NO LEAK ok = type(result) is str and "passed" in result.lower() # AUTOTEST - NO LEAK
elif step == "ko_check": 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: else:
ok = type(result) is str and "passed" in result.lower() # NORMAL TEST 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) ret = self.components["digital_io"].set_bit_verify(0, 1, 0)
else: else:
result = None #result = None
ok = None ok = None
results={"ok":ok}
results.update(data)
super().get([{ super().get([{
"time": data.get("time", None), "time": data.get("time", None),
"results": { "results": results
"ok": ok, #"results": {
"result": result, #"ok": ok,
"data": data["tecna_t3"], #"result": result,
}, #"data": data["tecna_t3"],
#},
}], override=override, fail=ok is False) }], override=override, fail=ok is False)
def visualize(self, data=None): def visualize(self, data=None):
if data is None: if data is None:
data = {} data = {}
d = data.get("results", {}).get("data", {}) d = data.get("results", {}).get("tecna_t3", {})
for k, l in { for k, l in {
"Running test: active phase": self.test_phase_l, "Running test: active phase": self.test_phase_l,
"Real time test pressure output": self.circuit_pressure_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, "Real time pressure line regulator": self.regulated_pressure_l,
# "Active alarm flags": self._l, # "Active alarm flags": self._l,
"Running test: test type": self.test_type_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: 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.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.setEnabled(True)
self.start_b.setDefault(True)
self.start_b.setFocus()
self.stop_b.setEnabled(False) self.stop_b.setEnabled(False)
else: else:
if self.step is not None: if self.step is not None:

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
import sys import sys
import time
import weakref import weakref
from datetime import datetime
from lib.helpers import timing from lib.helpers import timing
from PyQt5.QtCore import Qt, QTimer, pyqtSignal from PyQt5.QtCore import Qt, QTimer, pyqtSignal
@ -119,6 +121,7 @@ class Test_Test(Widget):
self.last = None self.last = None
def get(self, data=None, override=False, fail=False, preserve_counter=False, skip_delay=False): 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 if self.done: # avoid proccessing if completed
return return
if data is None: if data is None:
@ -129,18 +132,19 @@ class Test_Test(Widget):
data = self.last if self.last is not None else {} data = self.last if self.last is not None else {}
else: else:
data = data[-data_usable.index(True) - 1] data = data[-data_usable.index(True) - 1]
if data.get("time", None) is None: data["time"] = datetime.now().strftime("%H:%M:%S")
data["time"] = timing()
if fail: if fail:
result_ok = False result_ok = False
elif override: elif override:
result_ok = True result_ok = True
else: else:
result_ok = data.get("results", {}).get("ok", None) result_ok = data.get("results", {}).get("ok", None)
duration=cur_timing - self.start_time
data.pop("step",None)
self.last = { self.last = {
**data, **data,
"overridden": override, "overridden": override,
"duration": timing() - self.start_time, "duration": float(f"{duration:.2f}"),
"ok": result_ok, "ok": result_ok,
} }
if fail: if fail: