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

View File

@ -12,7 +12,7 @@ SET TEAR ON
CLS
DMATRIX 82,230,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
CODEPAGE 1252
TEXT 212,357,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}"
TEXT 212,357,"ROMAN.TTF",180,1,7,"{RECIPE}-{DD}{MO}{YY}{SN5}"
DMATRIX 82,129,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
DMATRIX 82,28,138,138,x3,22,22,"{RECIPE}-{DD}{MO}{YY}{SN5}"
PRINT 1,1

View File

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

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_max_percent: 5
test_time: 10
test_pressure_min_delta: 5
test_pressure_qneg: 5
test_pressure: 9000
test_pressure_max_delta: 5
test_pressure_qpos: 5
flush_time: 1
flush_pressure: 100

View File

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

View File

@ -10,7 +10,7 @@ neo_pixels: present
remote_api: absent
tecna_t3: present
vision_saver: present
vision: absent
vision: present
screwdriver: present
[tecna_t3]
@ -29,3 +29,67 @@ description_field: descrizione
[label_printer]
platform: windows
printer: zd420
[recipes_defaults]
codice_ricetta: specificare ricetta
cliente: IVECO
part_number: specificare part number
config_elettrovalvole: 0
warning_img:
dimensione_lotto_abilitata:
istruzione_abilitata: x
numero nastri (n):0
numero sensori anello (sa):0
numero sensori presenza (sp):0
prova_tenuta_abilitata: x
tempo_pre_riempimento: 0
pressione_pre_riempimento: 5000
tempo_riempimento: 5
tempo_assestamento: 10
percentuale_minima_pressione_assestamento: 5
percentuale_massima_pressione_assestamento: 5
tempo_di_test: 10
pressione_di_test_delta_minimo: 30
pressione_di_test: 5000
pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
prova_tenuta_abilitata_2:
tempo_pre_riempimento_2: 0
pressione_pre_riempimento_2: 1000
tempo_riempimento_2: 5
tempo_assestamento_2: 5
percentuale_minima_pressione_assestamento_2: 5
percentuale_massima_pressione_assestamento_2: 5
tempo_di_test_2: 5
pressione_di_test_delta_minimo_2: 200
pressione_di_test_2: 1000
pressione_di_test_delta_massimo_2: 200
tempo_svuotamento_2: 1
pressione_svuotamento_2: 100
stampa_etichetta_abilitata: x
modello_etichetta: ETA30x16_203dpi.prn
descrizione: inserire descrizione ricetta
[autotest_leak]
enabled: true
pre_filling_time: 0
pre_filling_pressure: 1000
filling_time: 15
settling_time: 10
settling_pressure_min_percent: 5
settling_pressure_max_percent: 5
test_time: 10
test_pressure_qneg: 10
test_pressure: 7000
test_pressure_qpos: 5
flush_time: 1
flush_pressure: 100
relay_config: 1

View File

@ -39,3 +39,19 @@ pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
config_elettrovalvole: 0
[autotest_leak]
enabled: true
pre_filling_time: 0
pre_filling_pressure: 1000
filling_time: 5
settling_time: 10
settling_pressure_min_percent: 5
settling_pressure_max_percent: 5
test_time: 10
test_pressure_qneg: 5
test_pressure: 9000
test_pressure_qpos: 5
flush_time: 1
flush_pressure: 100
relay_config: 1

View File

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

View File

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

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 {
id: 1
name: 'hs-ok'
name: 'ok'
color: '0x55AA55'
}
item {
id: 2
name: 'hs-ko'
name: 'ko'
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]
name: TERMORESTRINGENTE
instruction: CONTROLLARE PRESENZA TERMORESTRINGENTE
neural_network: hs5-20000
type: global
# POINTS FORMAT:
# point_name: point_center point_size fill_color border_color border_thickness shape

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 144 KiB

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:
:: Set-ExecutionPolicy Unrestricted -Scope CurrentUser
pip install -r src/requirements.txt
mkdir tmp
cd tmp
:: Advantech XNAVI
Invoke-WebRequest -uri "https://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-2BZC0F1" -usebasicparsing -outfile xnavi.zip
:: GXIPY
Invoke-WebRequest -uri "https://dahengimaging.com/downloads/Galaxy_Windows_EN_32bits%2064bits_1.18.2208.9301.zip" -OutFile Galaxy_Windows_EN_32bits_64bits_1.18.2208.9301.zip
Invoke-WebRequest -uri "https://dahengimaging.com/downloads/Galaxy_Windows_EN_32bits%2064bits_1.18.2208.9301.zip" -usebasicparsing -OutFile Galaxy_Windows_EN_32bits_64bits_1.18.2208.9301.zip

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
info = {r: self.read(r) for r in [
"Real time test pressure output",
"Real time differential pressure output",
"Real time pressure line regulator",
"Active alarm flags",
"Active test program number",
#"Real time differential pressure output",
#"Active alarm flags",
#"Active test program number",
"Running test: active phase",
"Running test: test type",
"Running test: measured leak",
"Running test: sequence index",
"Digital inputs status (mask)",
# "Digital outputs status (mask)",
"Digital outputs status (mask)",
]}
if self.model == "t3p":
pass
@ -222,9 +223,12 @@ class TecnaMarpossProvasetT3(ModbusComponent):
"Active not severe alarm flags",
]})
else:
raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.")
raise NotImplementedError(f"Tecna t3 model {self.model!r} not implemented.")
if info["Running test: active phase"] == "FINE TEST": # "END TEST, WAITING THE START OF A NEW TEST":
info.update(self.get_test_results())
for round_me in ["measured leak"]:
if round_me in info.keys():
info.update({round_me:float(f"{info[round_me]:.2f}")})
self.log.debug(str(info))
super()._get([info])
@ -251,13 +255,13 @@ class TecnaMarpossProvasetT3(ModbusComponent):
def get_test_results(self):
self.log.info("getting test results")
return {r: self.read(r) for r in [
"Running test: phase backwards time",
#"Running test: phase backwards time",
"Running test: filling pressure",
"Running test: pressure at the end of settling",
"Running test: burst pressure",
#"Running test: burst pressure",
"Running test: measured leak",
"Running test: calculated leak flow rate",
"Running test: calculate RVP%",
#"Running test: calculated leak flow rate",
#"Running test: calculate RVP%",
"Running test: result",
]}
@ -277,7 +281,8 @@ class TecnaMarpossProvasetT3(ModbusComponent):
# **{769 - 1 + i: (recipe_name[i * 2 + 1] << 8) + recipe_name[i * 2] for i in range(8)}, # print field 2
"Print options": 0b0000000000000000 | self.saver_label_count << 12 | self.saver_print_on_fail << 8 | self.saver_label_template,
"Test type": "Leak Test",
"Test flags": 0b0110000001011100 if step.spec.get("autotest", False) is not True else 0b0110000001010100,
# "Test flags": 0b0110000001011100 if step.spec.get("autotest", False) is not True else 0b0110000001010100,
"Test flags": 0b0110100001010100 if step.spec.get("autotest", False) in ("ok_check","ko_check") else 0b0110000001010100,
"T0 - Pre-filling time": step.spec["pre_filling_time"],
"P0 - Pre-filling pressure": step.spec["pre_filling_pressure"],
"T1 - Filling time": step.spec["filling_time"],
@ -285,9 +290,9 @@ class TecnaMarpossProvasetT3(ModbusComponent):
"PR- - Min pressure tolerance %": step.spec["settling_pressure_min_percent"],
"PR+ - Max pressure tolerance % (P+)": step.spec["settling_pressure_max_percent"],
"T3 - Measure time": step.spec["test_time"],
"Q- Lower test leak limit": step.spec["test_pressure_min_delta"],
"Q- Lower test leak limit": step.spec["test_pressure_qneg"],
"PREL - Nominal test pressure": step.spec["test_pressure"],
"Q+ Upper test leak limit": step.spec["test_pressure_max_delta"],
"Q+ Upper test leak limit": step.spec["test_pressure_qpos"],
"FST - Discharge time": step.spec["flush_time"],
"FSL - Discharge limit": step.spec["flush_pressure"],
}

View File

@ -80,7 +80,7 @@ registers = {
"Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 1507, }],
"Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }],
"Running test: result": [46 - 1, {"dt": "16bit_uint", "decoding": {
1: "LEAK TEST PASSED (also used in Volume+Leak tests)",
1: "LEAK TEST PASSED",
2: "BURST TEST PASSED WITH BURST",
3: "BURST TEST PASSED WITHOUT BURST",
4: "APERTURE TEST PASSED",

View File

@ -59,7 +59,7 @@ registers = {
"Running test: calculated leak flow rate": [42 - 1, {"dt": "32bit_int", "f": 24, }],
"Running test: calculate RVP%": [44 - 1, {"dt": "32bit_int", }],
"Running test: result": [46 - 1, {"dt": "16bit_uint", "decoding": {
1: "LEAK TEST PASSED (also used in Volume+Leak tests)",
1: "LEAK TEST PASSED",
2: "BURST TEST PASSED WITH BURST",
3: "BURST TEST PASSED WITHOUT BURST",
4: "APERTURE TEST PASSED",

View File

@ -57,7 +57,7 @@ else:
class Vision(Component):
"""everything is expected the have shape with height (y) first then width (x)"""
"""everything is expected to have shape with height (y) first then width (x)"""
status_signal = pyqtSignal(object)
loading_model_signal = pyqtSignal(object)
@ -66,6 +66,7 @@ class Vision(Component):
super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
self.lock = QMutex()
self.simulate = "--sim-vision" in sys.argv
self.vision_config = None
def start(self):
self.model = None
@ -96,7 +97,7 @@ class Vision(Component):
self.render_consumer.out.connect(self.process_render_consumed)
super().start()
def config_changed(self):
def config_changed(self,vision_recipe=None):
# OBJECT DETECTION
self.detection_threshold = float(self.config[self.name].get("detection_threshold", 0.5))
# recipe
@ -104,7 +105,8 @@ class Vision(Component):
self.labels = None
# LOAD RECIPE
self.recipes_dir = Path(self.config[self.name].get("recipes_dir", "./config/vision/recipes"))
self.set_recipe(None)
self.set_recipe(vision_recipe)
self.vision_recipe=vision_recipe
self.recipe_watcher = QFileSystemWatcher([])
self.recipe_watcher.fileChanged.connect(self._set_recipe)
# LOAD MODEL
@ -119,9 +121,11 @@ class Vision(Component):
if "--no-tflite" in sys.argv:
self.allowed_modes.pop("edgetpu", None)
self.allowed_modes.pop("tflite", None)
self.load_model(self.config[self.name].get("neural_network", None))
if self.vision_config is not None:
self.load_model(self.vision_config["neural_network"])
# LOAD LABELS
label_map = label_map_util.load_labelmap("./config/vision/labels/labels.pbtxt")
label_file="labels" if vision_recipe is None else vision_recipe
label_map = label_map_util.load_labelmap(f"./config/vision/labels/{label_file}.pbtxt")
self.num_classes = len(label_map.item)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=self.num_classes, use_display_name=True)
self.category_index = label_map_util.create_category_index(categories)
@ -148,7 +152,7 @@ class Vision(Component):
return pow((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2, 1 / 2)
def clear_recipe(self):
self.recipe = None
self.recipe_name = None
self.markers = {}
self.zones = {}
self.labels = {}
@ -170,6 +174,7 @@ class Vision(Component):
if len(read) != 1 or self.recipe_path not in read:
raise AssertionError("Recipe could not be read.")
os.path.splitext(os.path.basename(read[0]))[0]
self.vision_config = config._sections.get("general", None)
self.markers = self.parse_markers(config._sections.get("markers", None))
self.zones = self.parse_zones(config._sections.get("zones", None))
self.labels = self.parse_labels(config._sections.get("labels", None))
@ -179,7 +184,7 @@ class Vision(Component):
self.log.exception(f"Error reading {self.recipe_path!r}:")
self.clear_recipe()
self.status_signal.emit({
"recipe": self.recipe,
"recipe": self.recipe_name,
"markers": self.markers,
"zones": self.zones,
"labels": self.labels,
@ -189,8 +194,8 @@ class Vision(Component):
if recipe is None:
self.clear_recipe()
else:
self.recipe = recipe
self._set_recipe(self.recipes_dir / str(recipe))
self.recipe_name = recipe.split(".")[0]
self._set_recipe(self.recipes_dir / f"{self.recipe_name}.ini")
def parse_markers(self, config=None):
if config is None:
@ -434,11 +439,104 @@ class Vision(Component):
parsed_detections.append(detection)
return parsed_detections
def check_features_targeted(self, frame, lock=True):
parsed_detections = []
for zone_name,zone in self.zones.items():
y1,x1,y2,x2=int(zone["box"][0]),int(zone["box"][1]),int(zone["box"][2]),int(zone["box"][3])
crop = frame[y1:y2,x1:x2]
if self.interpreter is not None and frame.shape != self.interpreter.get_input_details()[0]["shape"][1:3]:
tensor = np.expand_dims(cv2.resize(crop, self.interpreter.get_input_details()[0]["shape"][1:3], interpolation=cv2.INTER_LINEAR), axis=0)
else:
frame_resized = cv2.resize(crop, (256, 256), interpolation=cv2.INTER_LINEAR)
tensor = tf.convert_to_tensor(np.asarray(frame_resized))
tensor = tensor[tf.newaxis, ...]
# tensor = np.expand_dims(frame, axis=0)
# Run inference
if lock:
self.lock.lock()
if self.simulate or self.tf_mode == "simulation":
detections = {
"detection_scores": [[1.0]],
"detection_boxes": [[[0.2, 0.2, 0.8, 0.8]]],
"detection_classes": [[1]],
}
if lock:
self.lock.unlock()
elif self.tf_mode in {"edgetpu", "tflite"}:
i_d = self.interpreter.get_input_details()
# print(i_d)
o_d = self.interpreter.get_output_details()
# print(o_d)
self.interpreter.set_tensor(i_d[0]["index"], tensor)
self.interpreter.invoke()
# PARSE TFLITE DETECTIONS
# signature_list = self.interpreter._get_full_signature_list()
# if signature_list:
# if len(signature_list) > 1:
# raise ValueError("Only support model with one signature.")
# signature = signature_list[next(iter(signature_list))]
# # count = int(self.interpreter.get_tensor(signature["outputs"]["output_0"])[0])
# scores = self.interpreter.get_tensor(signature["outputs"]["output_1"])[0]
# class_ids = self.interpreter.get_tensor(signature["outputs"]["output_2"])[0]
# boxes = self.interpreter.get_tensor(signature["outputs"]["output_3"])[0]
if self.interpreter.get_tensor(o_d[3]["index"]).size == 1:
boxes = self.interpreter.get_tensor(o_d[0]["index"])[0]
class_ids = self.interpreter.get_tensor(o_d[1]["index"])[0]
scores = self.interpreter.get_tensor(o_d[2]["index"])[0]
# count = int(self.interpreter.get_tensor(o_d[3]["index"])[0])
else:
scores = self.interpreter.get_tensor(o_d[0]["index"])[0]
boxes = self.interpreter.get_tensor(o_d[1]["index"])[0]
# count = int(self.interpreter.get_tensor(o_d[2]["index"])[0])
class_ids = self.interpreter.get_tensor(o_d[3]["index"])[0]
if lock:
self.lock.unlock()
detections = {
"detection_scores": [scores],
"detection_boxes": [boxes],
"detection_classes": [map(lambda class_id: class_id + 1, class_ids)],
}
else:
detections = self.model(tensor)
if lock:
self.lock.unlock()
detections = {
"detection_scores": detections["detection_scores"].numpy().tolist(),
"detection_boxes": detections["detection_boxes"].numpy().tolist(),
"detection_classes": detections["detection_classes"],
}
# WARNING: results other than the ones related to tensor[-1] will be discarded
for d_score, d_box, d_class in zip( # , d_mask in zip(
detections["detection_scores"][-1],
detections["detection_boxes"][-1],
detections["detection_classes"][-1],
# detections["detection_masks"][-1],
):
if d_score < self.detection_threshold:
continue
box = list(d_box)
box = [i * s for i, s in zip(box, crop.shape[:2] * 2)] # rescale detection to frame size
box_real=[box[0]+y1,box[1]+x1,box[2]+y1,box[3]+x1]
detection = {
"score": d_score,
"box": box_real,
"class": self.category_index[int(d_class)],
# "mask": d_mask,
"center": self.get_center(box),
"size": self.get_size(box),
}
parsed_detections.append(detection)
break # keep only first detection
return parsed_detections
def detections_to_items(self, detections):
# DRAW DETECTIONS
if detections is not None and len(detections):
style = {
"border_thickness": 25,
"border_thickness": 5,
"fill_color": QColor("#00000000"),
"shape": "rect",
"convert_negative_placement": False,
@ -460,7 +558,7 @@ class Vision(Component):
# MATCH DETECTIONS WITH RECIPE
results = dict.fromkeys(self.zones)
for detection in detections:
# find closest zone center to the detection
# find the closest zone center to the detection
# filtering out those that do not contain the detection
min_distance = sys.maxsize
closest_zone = None
@ -586,7 +684,7 @@ class Vision(Component):
**style,
"border_color": Qt.green if item["ok"] else Qt.red,
}
return items
return items
else:
return {}
@ -744,7 +842,11 @@ class Vision(Component):
# VISION_CONSUMER TASK
if consumable is None:
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)
return {"detections": detections, "results": results}

View File

@ -60,8 +60,8 @@ def init_db():
# "connector": {"connector": row["connector"]},
# "barcodes": {"serial": ""},
# "resistance": {"scale": 500, "expected": float(row["resistance_expected"]), "tolerance": float(row["resistance_tolerance"])},
# "leak_1": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_min_delta": 100, "test_pressure": 1000, "test_pressure_max_delta": 100, "flush_time": 1, "flush_pressure": 100},
# "leak_2": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_min_delta": 100, "test_pressure": 1000, "test_pressure_max_delta": 100, "flush_time": 1, "flush_pressure": 100},
# "leak_1": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
# "leak_2": {"pre_filling_time": 1, "pre_filling_pressure": 1000, "filling_time": 1, "settling_time": 1, "settling_pressure_min_percent": 5, "settling_pressure_max_percent": 5, "test_time": 5, "test_pressure_qneg": 100, "test_pressure": 1000, "test_pressure_qpos": 100, "flush_time": 1, "flush_pressure": 100},
# "vision": {"recipe": "termorestringente_923578.ini"},
# "print": {"template": "EtichettaR5.prn", },
# }.items():

View File

@ -10,7 +10,7 @@ from .users import Users
class Archive(BaseModel):
id = AutoField(primary_key=True, unique=True, null=False)
time = DateTimeField(unique=True, null=False, default=datetime.now)
time = DateTimeField(unique=True, null=False, default=datetime.now())
user = ForeignKeyField(Users, Users.username, null=False)
result = BooleanField(null=False)
overridden = BooleanField(null=False)
@ -22,7 +22,11 @@ class Archive(BaseModel):
@classmethod
@db.atomic()
def archive(cls, test_data, result, overridden):
time=datetime.now()
test_data["time"]=time.strftime("%d/%m/%Y %H:%M:%S")
test_data["user"]=Users.get_session().username
return cls.create(
time=time,
user=Users.get_session().user,
result=result,
overridden=overridden,

View File

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

View File

@ -48,7 +48,7 @@ class ConfigReader(QObject):
def read_config_file(self, config_path):
config_path = str(config_path)
config = ConfigParser(*self._args, **self._kwargs)
config = ConfigParser(*self._args, **self._kwargs, allow_no_value=True,comment_prefixes="#",inline_comment_prefixes="#")
read = config.read(config_path)
if len(read) != 1 or config_path != read[0]:
raise AssertionError(f"Config file {config_path} could not be read.")

View File

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

View File

@ -68,7 +68,7 @@ try:
from lib.helpers import ConfigReader
from PyQt5.QtCore import QObject, QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMessageBox
from ui import About, Archive, Login, Main_Window, Test, Users_Management
from ui import About, Archive, Login, Main_Window, Test, Users_Management, Recipe_Selection
if "--vision" in sys.argv:
from components import GalaxyCamera, NeoPixels, UVCCamera, Vision, VisionSaver
@ -166,23 +166,22 @@ try:
Archive(hide_cloud_image="vision_saver" not in self().components)))
if "--archive" in sys.argv:
self.main_window.archive_a.trigger()
self.main_window.about_a.triggered.connect(
lambda checked, self=weakref.ref(self): self().main_window.open_dialog(About()))
if "--about" in sys.argv:
self.main_window.about_a.trigger()
self.main_window.admin_m.menuAction().setVisible(
False) # admin menu should not be visible before an admin logs in
# admin menu should not be visible before an admin logs in
self.main_window.admin_m.menuAction().setVisible(False)
self.main_window.about_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(About()))
self.main_window.quit_a.triggered.connect(quit_app)
self.main_window.users_management_a.triggered.connect(
lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Users_Management()))
self.main_window.users_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Users_Management()))
self.main_window.table_selection_a.triggered.connect(self.set_recipe_mode_table)
self.main_window.barcode_selection_a.triggered.connect(self.set_recipe_mode_barcode)
if "--users-management" in sys.argv:
self.main_window.users_management_a.trigger()
# self.main_window.recipes_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Recipes_Management()))
# if "--recipes-management" in sys.argv:
# self.main_window.recipes_management_a.trigger()
# self.main_window.steps_management_a.triggered.connect(lambda checked, self=weakref.ref(self): self().main_window.open_dialog(Steps_Management()))
# if "--steps-management" in sys.argv:
# self.main_window.steps_management_a.trigger()
# CONFIG-SPECIFIC MENU ENTRY ACTIVATION
if "tecna_t3" in self.components and (
"--enable-saving-tecna-recipes" in sys.argv or self.config.get("tecna_t3", {}).get("saver",
None) == "present"):
@ -192,9 +191,8 @@ try:
self.main_window.save_tecna_recipes_a.trigger()
else:
self.main_window.save_tecna_recipes_a.setVisible(False)
self.main_window.barcode_selection_a.setVisible(self.config["hardware_config"]["barcode_recipe_selection"] == "present")
self.main_window.table_selection_a.triggered.connect(self.set_recipe_mode_table)
self.main_window.barcode_selection_a.triggered.connect(self.set_recipe_mode_barcode)
# OPEN LOGIN TAB
self.open_login()
# SHOW MAIN WINDOW
@ -220,16 +218,23 @@ try:
else:
self.main_window.admin_m.menuAction().setVisible(False)
# open test
self.main_window.open_tab(Test(self.config, self.components))
self.main_window.open_tab(Test(self.config, self.components,self))
else:
self.main_window.admin_m.menuAction().setVisible(False)
def logout(self):
if type(self.main_window.centralWidget) is Test:
self.main_window.centralWidget.change_recipe()
Users.logout()
self.main_window.admin_m.menuAction().setVisible(False)
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):
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 peewee import TextField
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QSize
from PyQt5.QtWidgets import (QAbstractItemView, QComboBox, QDialog,
QGridLayout, QHeaderView, QLineEdit, QMessageBox,
QPlainTextEdit, QPushButton)
@ -148,6 +148,7 @@ class Combo_Box_Cell_Widget(QComboBox, Cell):
class External_Dialog_Cell_Widget(QPushButton, Cell):
def __init__(self, action=None, readonly=True, autocomplete=None, field_name=None, field_alias=None, field=None, row_number=None, crud=None):
self.dialog = QDialog()
self.dialog.resize(QSize(800,800))
self.editor = QPlainTextEdit()
self.dialog.setLayout(QGridLayout())
self.dialog.layout().setSpacing(0)

View File

@ -15,9 +15,9 @@ class Leak_Step_Editor(Editor):
"settling_pressure_max_percent": self.settling_pressure_max_percent_sb,
# test
"test_time": self.test_time_sb,
"test_pressure_min_delta": self.test_pressure_min_delta_sb,
"test_pressure_qneg": self.test_pressure_qneg_sb,
"test_pressure": self.test_pressure_sb,
"test_pressure_max_delta": self.test_pressure_max_delta_sb,
"test_pressure_qpos": self.test_pressure_qpos_sb,
# flush
"flush_time": self.flush_time_sb,
"flush_pressure": self.flush_pressure_sb,

View File

@ -221,7 +221,7 @@
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="test_pressure_min_delta_sb">
<widget class="QSpinBox" name="test_pressure_qneg_sb">
<property name="minimum">
<number>0</number>
</property>
@ -238,7 +238,7 @@
</widget>
</item>
<item row="6" column="2">
<widget class="QSpinBox" name="test_pressure_max_delta_sb">
<widget class="QSpinBox" name="test_pressure_qpos_sb">
<property name="maximum">
<number>9999</number>
</property>

View File

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

View File

@ -128,8 +128,8 @@ class Recipe_Selection(Widget):
self.export_b.setVisible(False)
self.delete_all_b.setVisible(False)
# TESTING
if "--auto-select" in sys.argv or "--test" in sys.argv:
recipe = "5802850925"
if "--auto-select" in sys.argv:
recipe = "000952054"
cn = self.crud.select_index["name"]
self.crud.db_tw.clearSelection()
for rn in range(1, self.crud.db_tw.rowCount()):
@ -214,9 +214,9 @@ class Recipe_Selection(Widget):
"settling_pressure_min_percent": int(row.get("percentuale_minima_pressione_assestamento", defaults["percentuale_minima_pressione_assestamento"])),
"settling_pressure_max_percent": int(row.get("percentuale_massima_pressione_assestamento", defaults["percentuale_massima_pressione_assestamento"])),
"test_time": int(row.get("tempo_di_test", defaults["tempo_di_test"])),
"test_pressure_min_delta": int(row.get("pressione_di_test_delta_minimo", defaults["pressione_di_test_delta_minimo"])),
"test_pressure_qneg": int(row.get("pressione_di_test_delta_minimo", defaults["pressione_di_test_delta_minimo"])),
"test_pressure": int(row.get("pressione_di_test", defaults["pressione_di_test"])),
"test_pressure_max_delta": int(row.get("pressione_di_test_delta_massimo", defaults["pressione_di_test_delta_massimo"])),
"test_pressure_qpos": int(row.get("pressione_di_test_delta_massimo", defaults["pressione_di_test_delta_massimo"])),
"flush_time": int(row.get("tempo_svuotamento", defaults["tempo_svuotamento"])),
"flush_pressure": int(row.get("pressione_svuotamento", defaults["pressione_svuotamento"])),
"relay_config": int(row.get("config_elettrovalvole", defaults["config_elettrovalvole"]))
@ -229,9 +229,9 @@ class Recipe_Selection(Widget):
"settling_pressure_min_percent": int(row.get("percentuale_minima_pressione_assestamento_2", defaults["percentuale_minima_pressione_assestamento_2"])),
"settling_pressure_max_percent": int(row.get("percentuale_massima_pressione_assestamento_2", defaults["percentuale_massima_pressione_assestamento_2"])),
"test_time": int(row.get("tempo_di_test_2", defaults["tempo_di_test_2"])),
"test_pressure_min_delta": int(row.get("pressione_di_test_delta_minimo_2", defaults["pressione_di_test_delta_minimo_2"])),
"test_pressure_qneg": int(row.get("pressione_di_test_delta_minimo_2", defaults["pressione_di_test_delta_minimo_2"])),
"test_pressure": int(row.get("pressione_di_test_2", defaults["pressione_di_test_2"])),
"test_pressure_max_delta": int(row.get("pressione_di_test_delta_massimo_2", defaults["pressione_di_test_delta_massimo_2"])),
"test_pressure_qpos": int(row.get("pressione_di_test_delta_massimo_2", defaults["pressione_di_test_delta_massimo_2"])),
"flush_time": int(row.get("tempo_svuotamento_2", defaults["tempo_svuotamento_2"])),
"flush_pressure": int(row.get("pressione_svuotamento_2", defaults["pressione_svuotamento_2"])),
"relay_config": int(row.get("config_elettrovalvole_2", defaults["config_elettrovalvole_2"]))
@ -434,9 +434,9 @@ class Recipe_Selection(Widget):
"percentuale_minima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_min_percent"],
"percentuale_massima_pressione_assestamento": steps["leak_1"].spec["settling_pressure_max_percent"],
"tempo_di_test": steps["leak_1"].spec["test_time"],
"pressione_di_test_delta_minimo": steps["leak_1"].spec["test_pressure_min_delta"],
"pressione_di_test_delta_minimo": steps["leak_1"].spec["test_pressure_qneg"],
"pressione_di_test": steps["leak_1"].spec["test_pressure"],
"pressione_di_test_delta_massimo": steps["leak_1"].spec["test_pressure_max_delta"],
"pressione_di_test_delta_massimo": steps["leak_1"].spec["test_pressure_qpos"],
"tempo_svuotamento": steps["leak_1"].spec["flush_time"],
"pressione_svuotamento": steps["leak_1"].spec["flush_pressure"],
"prova_tenuta_abilitata_2": "x" if recipe.spec["leak_2"] else "",
@ -447,9 +447,9 @@ class Recipe_Selection(Widget):
"percentuale_minima_pressione_assestamento_2": steps["leak_2"].spec["settling_pressure_min_percent"],
"percentuale_massima_pressione_assestamento_2": steps["leak_2"].spec["settling_pressure_max_percent"],
"tempo_di_test_2": steps["leak_2"].spec["test_time"],
"pressione_di_test_delta_minimo_2": steps["leak_2"].spec["test_pressure_min_delta"],
"pressione_di_test_delta_minimo_2": steps["leak_2"].spec["test_pressure_qneg"],
"pressione_di_test_2": steps["leak_2"].spec["test_pressure"],
"pressione_di_test_delta_massimo_2": steps["leak_2"].spec["test_pressure_max_delta"],
"pressione_di_test_delta_massimo_2": steps["leak_2"].spec["test_pressure_qpos"],
"tempo_svuotamento_2": steps["leak_2"].spec["flush_time"],
"pressione_svuotamento_2": steps["leak_2"].spec["flush_pressure"],
"test_visione_abilitato": recipe.spec["vision"],

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):
def __init__(self, config, components=None):
def __init__(self, config, components=None,main_window=None):
super().__init__()
self.main_window=main_window
self.config = config
self.components = components
# GET LOGGER
self.log = logging.getLogger("Test")
# SHOW MACHINE DESCRIPTION
self.machine_description_l.setText(self.config.get("machine", {}).get("description", "N/A"))
# SHOW USERNAME
# SHOW USERNAME
session = Users.get_session()
self.user_l.setText(session.username)
@ -91,9 +90,9 @@ class Test(Widget):
"count_end": Test_Assembly(img_path=None, text=u"LOTTO TERMINATO, PREMERE CONTINUA PERCOMINCIARNE UNO NUOVO", widget=Test_Count_End(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces)),
"done": Test_Assembly(img_path=self.select_step_img("success"), text=u"COLLAUDO COMPLETATO", widget=None),
"emergency": Test_Assembly(img_path=self.select_step_img("reset_emergency"), text=u"EMERGENZA INTERVENUTA - RIPRISTINARE PULSANTE E SELEZIONARE \"RESET EMERGENZA\" DAL MEN\u00d9 \"STRUMENTI\"", widget=None),
"fail": Test_Assembly(img_path=self.select_step_img("fail"), text=u"CICLO INTERROTTO, PREMERE CONTINUA PER COMINCIARE UN NUOVO CICLO", widget=Test_Fail()),
"fail": Test_Assembly(img_path=self.select_step_img("fail"), text=u"CICLO INTERROTTO, PREMERE CONTINUA PER COMINCIARE UN NUOVO CICLO", widget=Test_Fail(parent=self)),
"leak_1": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces,parent=self)),
"leak_2": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces)),
"leak_2": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces,parent=self)),
"instruction": Test_Assembly(img_path=None, text=u"ESEGUIRE LE OPERAZIONI DI MONTAGGIO INDICATE IN FIGURA", widget=Test_Instructions(components=self.components, recipe=self.recipe,bench_name=self.config.machine_id, step=self.step)),
"print": Test_Assembly(img_path=self.select_step_img("print"), text=u"STAMPA ETICHETTA IN CORSO", widget=None),
"resistance": Test_Assembly(img_path=None, text=u"COLLEGARE CONNETTORE ELETTRICO PER EFFETTUARE PROVA RESISTENZA", widget=Test_Resistance(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces)),
@ -113,7 +112,8 @@ class Test(Widget):
self.autotesting_reason = None
self.autotest_cycle_steps = None
if "--no-autotest" not in sys.argv:
self.autotest_period = 12 * 60 * 60 * 1000
self.autotest_period = 8.5 * 60 * 60 * 1000 # 8.5 HOURS
# self.autotest_period = 12 * 60 * 60 * 1000 # 12 HOURS
if not self.config["autotest_done"]:
self.request_autotest("init")
else:
@ -314,6 +314,8 @@ class Test(Widget):
for i, step in enumerate(steps):
if i in skip:
continue
if step.type == "vision":
self.components["vision"].config_changed(vision_recipe=self.recipe.name)
if step.type == "count":
count_found = True
if "warning_img" in step.spec:
@ -349,6 +351,7 @@ class Test(Widget):
self.cycle_steps = steps
self.check_steps_dependencies(self.cycle_steps)
leak_autotest_steps=[]
# CONFIGURE LEAK AUTOTEST PARAMETERS
if self.config["autotest_leak"]["enabled"]=="true":
l_at_1=copy.deepcopy(self.config["autotest_leak"])
l_at_1.pop("enabled")
@ -357,6 +360,8 @@ class Test(Widget):
l_at_2=copy.deepcopy(self.config["autotest_leak"])
l_at_2.pop("enabled")
l_at_2={a: float(x) for a, x in l_at_2.items()}
l_at_2["test_pressure_qneg"]=l_at_2["test_pressure_tt_qneg"]
l_at_2["test_pressure_qpos"]=l_at_2["test_pressure_tt_qpos"]
l_at_2["autotest"]="ok_check"
leak_autotest_steps=[Steps(type="leak_1",spec=l_at_1),Steps(type="leak_1",spec=l_at_2)]
@ -452,13 +457,32 @@ class Test(Widget):
self.data[step_name] = {}
if data is not None:
data["step"] = model_to_dict(self.step)
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["ok"] = self.data["ok"] and data.get("ok", False)
self.next()
def done(self, ok=True):
self.log.info("cycle done")
self.log.info("cycle done, saving data...")
#remove useless info
self.data.get("recipe",{}).get("spec",{}).pop("steps",None)
self.data.get("recipe",{}).get("spec",{}).pop("available_steps",None)
for leak in ["leak_1","leak_2"]:
if leak in self.data.keys():
self.data[leak]["results"]={k:self.data[leak]["results"]["tecna_t3"][k] for k in ["Running test: filling pressure",
"Running test: measured leak",
"Running test: pressure at the end of settling",
"Running test: result"]
}
if "vision" in self.data:
vision_test_1 = self.data.get("vision", {}).get("0", {})
out_paths = self.components["vision_saver"].save(
@ -471,6 +495,9 @@ class Test(Widget):
for vision in self.data.get("vision", {}).values():
vision.pop("frame", None)
vision.pop("render", None)
vision.pop("detections", None)
if "results" in vision.keys():
vision["results"].pop("results", None)
if self.autotesting:
self.data["autotest"] = True
self.data["autotest_reason"] = self.autotesting_reason
@ -483,6 +510,11 @@ class Test(Widget):
self.pieces["ok"] += 1
else:
self.pieces["ko"] += 1
else:
if self.autotesting_reason == "logout":
if ok:
self.main_window.show_login()
return archived
@staticmethod
@ -503,21 +535,19 @@ class Test(Widget):
self.log.info("cycle printed already compiled label")
# LABEL PRINT
recipe = archived.test_data.get("recipe", {})
leak_test_1 = archived.test_data.get("leak_1", {}).get("0", {})
leak_test_1 = archived.test_data.get("leak_1", {})
leak_test_1_step = leak_test_1.get("step", {})
leak_test_1_step_spec = leak_test_1_step.get("spec", {})
leak_test_1_results = leak_test_1.get("results", {})
leak_test_1_results_data = leak_test_1_results.get("data", {})
leak_test_2 = archived.test_data.get("leak_2", {}).get("0", {})
leak_test_2 = archived.test_data.get("leak_2", {})
leak_test_2_step = leak_test_2.get("step", {})
leak_test_2_step_spec = leak_test_2_step.get("spec", {})
leak_test_2_results = leak_test_2.get("results", {})
leak_test_2_results_data = leak_test_2_results.get("data", {})
psetminp_a = leak_test_1_step_spec.get("test_pressure", 0) * (100+leak_test_1_step_spec.get("test_pressure_min_delta", 0)/100)
psetmaxp_a = leak_test_1_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_1_step_spec.get("test_pressure_max_delta", 0)/100)
psetminp2_a = leak_test_2_step_spec.get("settling_pressure_min_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_min_delta", 0)/100)
psetmaxp2_a = leak_test_2_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_max_delta", 0)/100)
psetminp_a = leak_test_1_step_spec.get("test_pressure", 0) * (100+leak_test_1_step_spec.get("test_pressure_qneg", 0)/100)
psetmaxp_a = leak_test_1_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_1_step_spec.get("test_pressure_qpos", 0)/100)
psetminp2_a = leak_test_2_step_spec.get("settling_pressure_min_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_qneg", 0)/100)
psetmaxp2_a = leak_test_2_step_spec.get("settling_pressure_max_percent", 0) * (100+leak_test_2_step_spec.get("test_pressure_qpos", 0)/100)
printer_fields = self.step.spec
context = {
@ -525,6 +555,7 @@ class Test(Widget):
"RECIPE": self.labellify(recipe.get("name", "-")),
"CLIENT": self.labellify(recipe.get("client", "-")),
"PART": self.labellify(recipe.get("part_number", "-")),
"DESCRIPTION": self.labellify(recipe.get("description", "-")),
# STEP SPEC
"TPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_time", "-")),
"PPREFILL": self.labellify(leak_test_1_step_spec.get("pre_filling_pressure", "-")),
@ -544,24 +575,22 @@ class Test(Widget):
"PSETMAXP2_A": self.labellify(psetmaxp2_a),
"TTEST": self.labellify(leak_test_1_step_spec.get("test_time", "-")),
"TTEST2": self.labellify(leak_test_2_step_spec.get("test_time", "-")),
"PMIN": self.labellify(leak_test_1_step_spec.get("test_pressure_min_delta", "-")),
"PMIN2": self.labellify(leak_test_2_step_spec.get("test_pressure_min_delta", "-")),
"PMIN": self.labellify(leak_test_1_step_spec.get("test_pressure_qneg", "-")),
"PMIN2": self.labellify(leak_test_2_step_spec.get("test_pressure_qneg", "-")),
"PTEST": self.labellify(leak_test_1_step_spec.get("test_pressure", "-")),
"PTEST2": self.labellify(leak_test_2_step_spec.get("test_pressure", "-")),
"PMAX": self.labellify(leak_test_1_step_spec.get("test_pressure_max_delta", "-")),
"PMAX": self.labellify(leak_test_1_step_spec.get("test_pressure_qpos", "-")),
"TFLUSH": self.labellify(leak_test_1_step_spec.get("flush_time", "-")),
"PFLUSH": self.labellify(leak_test_1_step_spec.get("flush_pressure", "-")),
# ACTUAL TESTED VALUES
"RESTPB": self.labellify(leak_test_1_results_data.get("Running test: phase backwards time", "-")),
"RESPFILL": self.labellify(leak_test_1_results_data.get("Running test: filling pressure", "-")),
"RESPSET": self.labellify(leak_test_1_results_data.get("Running test: pressure at the end of settling", "-")),
"RESPSET2": self.labellify(leak_test_2_results_data.get("Running test: pressure at the end of settling", "-")),
"RESPB": self.labellify(leak_test_1_results_data.get("Running test: burst pressure", "-")),
"RESLEAK": self.labellify(leak_test_1_results_data.get("Running test: measured leak", "-")),
"RESLEAK2": self.labellify(leak_test_2_results_data.get("Running test: measured leak", "-")),
"RESFLOW": self.labellify(leak_test_1_results_data.get("Running test: calculated leak flow rate", "-")),
"RESRVP": self.labellify(leak_test_1_results_data.get("Running test: calculate RVP%", "-")),
"RESRES": self.labellify(leak_test_1_results_data.get("Running test: result", "-")),
"RESPFILL": self.labellify(leak_test_1_results.get("Running test: filling pressure", "-")),
"RESPFILL2": self.labellify(leak_test_2_results.get("Running test: filling pressure", "-")),
"RESPSET": self.labellify(leak_test_1_results.get("Running test: pressure at the end of settling", "-")),
"RESPSET2": self.labellify(leak_test_2_results.get("Running test: pressure at the end of settling", "-")),
"RESLEAK": self.labellify(leak_test_1_results.get("Running test: measured leak", "-")),
"RESLEAK2": self.labellify(leak_test_2_results.get("Running test: measured leak", "-")),
"RESRES": self.labellify(leak_test_1_results.get("Running test: result", "-")),
"RESRES2": self.labellify(leak_test_2_results.get("Running test: result", "-")),
# SERIAL DEFINITION
"SN": str(archived.id),
"SN4": f"{archived.id:0>4}",
@ -597,6 +626,13 @@ class Test(Widget):
# PRINT MAIN PRODUCT LABEL
compiled_label = self.components["label_printer"].print_label(label, context=context)
# if recipe.get("part_number", "-") == "5802814210 R.3":
# num_labels=2
# else:
# num_labels=1
#
# for i in range(num_labels):
# compiled_label = self.components["label_printer"].print_label(label, context=context)
self.log.info(f"Main label printed: {context!r}")
return compiled_label

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>842</width>
<height>118</height>
<width>1252</width>
<height>146</height>
</rect>
</property>
<property name="windowTitle">
@ -52,52 +52,7 @@
<property name="bottomMargin">
<number>3</number>
</property>
<item row="1" column="0" rowspan="2">
<widget class="QPushButton" name="change_recipe_b">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>40</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>CAMBIA DISEGNO</string>
</property>
</widget>
</item>
<item row="1" column="2" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="4" rowspan="2">
<item row="1" column="5" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -110,71 +65,6 @@
</property>
</spacer>
</item>
<item row="2" column="5">
<widget class="QLabel" name="pieces_count_l">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>12345</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="6" rowspan="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="5">
<widget class="QLabel" name="label_9">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>PEZZI FATTI</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="3" rowspan="2">
<widget class="QLabel" name="time_l">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>12345
567</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1" rowspan="2">
<widget class="QPushButton" name="cancel_b">
<property name="sizePolicy">
@ -201,14 +91,38 @@
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="1" column="7" rowspan="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="11">
<widget class="QLabel" name="machine_description_l">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QLabel" name="pieces_count_l">
<property name="font">
<font>
<pointsize>12</pointsize>
@ -217,25 +131,14 @@
</font>
</property>
<property name="text">
<string>N. DISEGNO:</string>
<string>12345</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="7">
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>OPERATORE:</string>
</property>
</widget>
</item>
<item row="1" column="8">
<item row="1" column="9">
<widget class="QLabel" name="recipe_l">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
@ -268,7 +171,7 @@
</widget>
</item>
<item row="2" column="8">
<widget class="QLabel" name="user_l">
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<pointsize>12</pointsize>
@ -277,11 +180,66 @@
</font>
</property>
<property name="text">
<string>-</string>
<string>OPERATORE:</string>
</property>
</widget>
</item>
<item row="1" column="9" rowspan="2">
<item row="1" column="4" rowspan="2">
<widget class="QLabel" name="time_l">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>12345
567</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>N. DISEGNO:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLabel" name="label_9">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>PEZZI FATTI</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="10" rowspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -297,11 +255,24 @@
</property>
</spacer>
</item>
<item row="0" column="0" colspan="10">
<widget class="QLabel" name="machine_description_l">
<item row="1" column="3" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="9">
<widget class="QLabel" name="user_l">
<property name="font">
<font>
<pointsize>16</pointsize>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
@ -309,6 +280,69 @@
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="2">
<widget class="QPushButton" name="change_recipe_b">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>40</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>CAMBIA DISEGNO</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="time_l_2">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>ULTIMO AUTOTEST:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="autotests_l">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>DD/MM/YY HH:MM</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>

View File

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

View File

@ -10,14 +10,24 @@ from ui.test_test import Test_Test
class Test_Fail(Test_Test):
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False):
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False,parent=None):
super().__init__(components=components, recipe=recipe, step=step, pieces=pieces, run_once=run_once, reset_on_start=reset_on_start, enable_override=enable_override)
self.continue_b.clicked.connect(lambda checked, self=weakref.ref(self): self().ok.emit(None))
self.parent=parent
self.discard_timer=QTimer()
self.discard_timer.timeout.connect(self.wait_discard)
def start(self, recipe=None, step=None, pieces=None):
show = super().start(recipe=recipe, step=step, pieces=pieces)
if show is False:
return show
if "discard_box" in self.parent.config["hardware_config"].keys():
if self.parent_assembly_widget is not None :
self.continue_b.setVisible(False)
self.discard_timer.start(100)
self.parent_assembly_widget().set_text(text="TEST KO - INSERIRE IL PEZZO COLLAUDATO NEL CONTENITORE DI SEGREGAZIONE SCARTI")
self.io_connection=self.components["digital_io"].out.connect(self.wait_discard)
self.visualize()
# TESTING
if "--test" in sys.argv:
@ -25,11 +35,21 @@ class Test_Fail(Test_Test):
self.test_timer.setSingleShot(True)
self.test_timer.timeout.connect(self.continue_b.click)
self.test_timer.start(500)
# /TESTING
return show
# def stop(self):
# super().stop()
def stop(self):
if "discard_box" in self.parent.config["hardware_config"].keys():
self.disconnect(self.io_connection)
super().stop()
def wait_discard(self,data=None):
if data is not None:
if len(data[0]["digital_io"]) == 0:
return
else:
sensor_index = int(self.parent.config["digital_io"]["discard_idx"])
byte_idx = int(sensor_index / 8)
bit_idx = sensor_index % 8
if data[0]["digital_io"][byte_idx][bit_idx]:
self.ok.emit(None)
# def reset(self):
# super().reset()

View File

@ -2,24 +2,33 @@ import sys
import time
import weakref
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QMessageBox, QDialog
from ui import Dialog
from ui.test_test import Test_Test
from components.Automation.BDaq import ErrorCode
class Test_Leak(Test_Test):
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False,parent=None):
super().__init__(components=components, recipe=recipe, step=step, pieces=pieces, run_once=run_once, reset_on_start=reset_on_start, enable_override=enable_override)
self.parent=parent
self.step=step
self.start_b.clicked.connect(self.start_test)
self.stop_b.clicked.connect(lambda checked, self=weakref.ref(self): self().components["tecna_t3"].stop_test())
self.parent=parent
self.show_instruction_b.setVisible("show_instructions" in self.parent.config["hardware_config"].keys())
self.show_instruction_b.clicked.connect(self.show_instruction)
def show_instruction(self):
dialog=Dialog()
dialog.setCentralWidget(self.parent.cycle_available_steps["instruction"])
dialog.show()
def start_test(self):
# print extra labels
if self.step.type == "leak_1":
self.parent.print_extra_labels()
self.components["tecna_t3"].start_test()
self.components["tecna_t3"].start_test()
def start(self, recipe=None, step=None, pieces=None):
# TESTING
@ -32,6 +41,17 @@ class Test_Leak(Test_Test):
if show is False:
return show
if "leak_2" in [s.type for s in self.parent.cycle_steps]:
if self.step.type=="leak_1":
self.test_num_l.setText("1/2")
else:
self.test_num_l.setText("2/2")
else:
self.test_num_l.setText("1/1")
self.recipe_pressure_l.setText(f"{self.step.spec['test_pressure']}")
self.leak_min_l.setText(f"{self.step.spec['test_pressure_qneg']}")
self.leak_max_l.setText(f"{self.step.spec['test_pressure_qpos']}")
# setup test loop
self.components["tecna_t3"].write_recipe(self.recipe, self.step)
self.get_connection = self.components["tecna_t3"].out.connect(self.get)
@ -102,7 +122,7 @@ class Test_Leak(Test_Test):
if step == "ok_check":
ok = type(result) is str and "passed" in result.lower() # AUTOTEST - NO LEAK
elif step == "ko_check":
ok = type(result) is str and "failed" in result.lower() # AUTOTEST - LEAK
ok = type(result) is str and "passed" in result.lower() # AUTOTEST - LEAK
else:
ok = type(result) is str and "passed" in result.lower() # NORMAL TEST
@ -112,25 +132,30 @@ class Test_Leak(Test_Test):
ret = self.components["digital_io"].set_bit_verify(0, 1, 0)
else:
result = None
#result = None
ok = None
results={"ok":ok}
results.update(data)
super().get([{
"time": data.get("time", None),
"results": {
"ok": ok,
"result": result,
"data": data["tecna_t3"],
},
"results": results
#"results": {
#"ok": ok,
#"result": result,
#"data": data["tecna_t3"],
#},
}], override=override, fail=ok is False)
def visualize(self, data=None):
if data is None:
data = {}
d = data.get("results", {}).get("data", {})
d = data.get("results", {}).get("tecna_t3", {})
for k, l in {
"Running test: active phase": self.test_phase_l,
"Real time test pressure output": self.circuit_pressure_l,
"Real time differential pressure output": self.leak_l,
#"Real time differential pressure output": self.leak_l,
"Running test: measured leak": self.leak_l,
"Real time pressure line regulator": self.regulated_pressure_l,
# "Active alarm flags": self._l,
"Running test: test type": self.test_type_l,
@ -156,6 +181,9 @@ class Test_Leak(Test_Test):
if self.parent_assembly_widget is not None:
self.parent_assembly_widget().set_text(text="COLLEGARE GLI ATTACCHI PNEUMATICI E PREMERE START PER INIZIARE LA PROVA TENUTA")
self.start_b.setEnabled(True)
self.start_b.setDefault(True)
self.start_b.setFocus()
self.stop_b.setEnabled(False)
else:
if self.step is not None:

File diff suppressed because it is too large Load Diff

View File

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