diff --git a/.gitignore b/.gitignore index 0de428e..51b4962 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ __pycache__/ /tmp/ /venv*/ runme_custom.sh +runme_custom.bat diff --git a/config/instruction_images/st-ten-5/5802815398.svg b/config/instruction_images/st-ten-5/5802815398.svg new file mode 100644 index 0000000..9989912 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802815398.svg @@ -0,0 +1,3090 @@ + + + +image/svg+xml diff --git a/config/instruction_images/st-ten-5/5802850925.svg b/config/instruction_images/st-ten-5/5802850925.svg index 390f819..97b6d20 100644 --- a/config/instruction_images/st-ten-5/5802850925.svg +++ b/config/instruction_images/st-ten-5/5802850925.svg @@ -8,7 +8,7 @@ version="1.1" id="svg5" xml:space="preserve" - inkscape:version="1.2.2 (1:1.2.2+202212051550+b0a8486541)" + inkscape:version="1.2.2 (732a01da63, 2022-12-09)" sodipodi:docname="5802850925.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -26,5206 +26,8588 @@ inkscape:document-units="mm" showgrid="false" inkscape:zoom="1.0570734" - inkscape:cx="751.13043" - inkscape:cy="242.17807" - inkscape:window-width="2560" - inkscape:window-height="1023" - inkscape:window-x="0" - inkscape:window-y="0" + inkscape:cx="618.21629" + inkscape:cy="308.87165" + inkscape:window-width="1920" + inkscape:window-height="1001" + inkscape:window-x="-9" + inkscape:window-y="-9" inkscape:window-maximized="1" inkscape:current-layer="layer1" /> + x="770.81818" + y="48.066025" + inkscape:svg-dpi="1" /> diff --git a/config/instruction_images/st-ten-5/5802850926.svg b/config/instruction_images/st-ten-5/5802850926.svg new file mode 100644 index 0000000..06ac2b0 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802850926.svg @@ -0,0 +1,72 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/config/instruction_images/st-ten-5/5802850929.svg b/config/instruction_images/st-ten-5/5802850929.svg new file mode 100644 index 0000000..42e7d5f --- /dev/null +++ b/config/instruction_images/st-ten-5/5802850929.svg @@ -0,0 +1,4750 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802850932.svg b/config/instruction_images/st-ten-5/5802850932.svg new file mode 100644 index 0000000..c4852b4 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802850932.svg @@ -0,0 +1,2374 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802850933.svg b/config/instruction_images/st-ten-5/5802850933.svg new file mode 100644 index 0000000..4a6fe8b --- /dev/null +++ b/config/instruction_images/st-ten-5/5802850933.svg @@ -0,0 +1,3816 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802850935.svg b/config/instruction_images/st-ten-5/5802850935.svg new file mode 100644 index 0000000..62762f8 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802850935.svg @@ -0,0 +1,4376 @@ + + + +image/svg+xml diff --git a/config/instruction_images/st-ten-5/5802850941.svg b/config/instruction_images/st-ten-5/5802850941.svg new file mode 100644 index 0000000..3d5311a --- /dev/null +++ b/config/instruction_images/st-ten-5/5802850941.svg @@ -0,0 +1,6647 @@ + + + +image/svg+xml diff --git a/config/instruction_images/st-ten-5/5802963590.svg b/config/instruction_images/st-ten-5/5802963590.svg new file mode 100644 index 0000000..ce7ffda --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963590.svg @@ -0,0 +1,4046 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963591.svg b/config/instruction_images/st-ten-5/5802963591.svg new file mode 100644 index 0000000..1a518bb --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963591.svg @@ -0,0 +1,149 @@ + + + +image/svg+xml diff --git a/config/instruction_images/st-ten-5/5802963593.svg b/config/instruction_images/st-ten-5/5802963593.svg new file mode 100644 index 0000000..2dbbcb5 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963593.svg @@ -0,0 +1,95 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963597.svg b/config/instruction_images/st-ten-5/5802963597.svg new file mode 100644 index 0000000..484d371 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963597.svg @@ -0,0 +1,4010 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963598.svg b/config/instruction_images/st-ten-5/5802963598.svg new file mode 100644 index 0000000..81055eb --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963598.svg @@ -0,0 +1,209 @@ + + + +image/svg+xml diff --git a/config/instruction_images/st-ten-5/5802963599.svg b/config/instruction_images/st-ten-5/5802963599.svg new file mode 100644 index 0000000..c5dce01 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963599.svg @@ -0,0 +1,2904 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963600.svg b/config/instruction_images/st-ten-5/5802963600.svg new file mode 100644 index 0000000..3154729 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963600.svg @@ -0,0 +1,3826 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963679.svg b/config/instruction_images/st-ten-5/5802963679.svg new file mode 100644 index 0000000..0946a18 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963679.svg @@ -0,0 +1,2414 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963681.svg b/config/instruction_images/st-ten-5/5802963681.svg new file mode 100644 index 0000000..77084ff --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963681.svg @@ -0,0 +1,79 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963683.svg b/config/instruction_images/st-ten-5/5802963683.svg new file mode 100644 index 0000000..9e1f1a0 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963683.svg @@ -0,0 +1,4423 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963684.svg b/config/instruction_images/st-ten-5/5802963684.svg new file mode 100644 index 0000000..13d7a84 --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963684.svg @@ -0,0 +1,9308 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5802963685.svg b/config/instruction_images/st-ten-5/5802963685.svg new file mode 100644 index 0000000..2f6c23f --- /dev/null +++ b/config/instruction_images/st-ten-5/5802963685.svg @@ -0,0 +1,3028 @@ + + + + diff --git a/config/instruction_images/st-ten-5/5803034807.svg b/config/instruction_images/st-ten-5/5803034807.svg deleted file mode 100644 index 38a60be..0000000 --- a/config/instruction_images/st-ten-5/5803034807.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - diff --git a/config/instruction_images/st-ten-5/img/mb1.png b/config/instruction_images/st-ten-5/img/mb1.png new file mode 100644 index 0000000..731a437 Binary files /dev/null and b/config/instruction_images/st-ten-5/img/mb1.png differ diff --git a/config/instruction_images/st-ten-5/img/mi1.PNG b/config/instruction_images/st-ten-5/img/mi1.PNG new file mode 100644 index 0000000..6b0f9d9 Binary files /dev/null and b/config/instruction_images/st-ten-5/img/mi1.PNG differ diff --git a/config/instruction_images/st-ten-5/img/mi2.PNG b/config/instruction_images/st-ten-5/img/mi2.PNG new file mode 100644 index 0000000..9db21ff Binary files /dev/null and b/config/instruction_images/st-ten-5/img/mi2.PNG differ diff --git a/config/instruction_images/st-ten-5/img/rb1.PNG b/config/instruction_images/st-ten-5/img/rb1.PNG new file mode 100644 index 0000000..3050451 Binary files /dev/null and b/config/instruction_images/st-ten-5/img/rb1.PNG differ diff --git a/config/instruction_images/st-ten-5/img/rb2.PNG b/config/instruction_images/st-ten-5/img/rb2.PNG new file mode 100644 index 0000000..4bf5efc Binary files /dev/null and b/config/instruction_images/st-ten-5/img/rb2.PNG differ diff --git a/config/instruction_images/st-ten-5/img/rm1.PNG b/config/instruction_images/st-ten-5/img/rm1.PNG new file mode 100644 index 0000000..33f0eeb Binary files /dev/null and b/config/instruction_images/st-ten-5/img/rm1.PNG differ diff --git a/config/instruction_images/st-ten-5/img/rm2.PNG b/config/instruction_images/st-ten-5/img/rm2.PNG new file mode 100644 index 0000000..ef1496a Binary files /dev/null and b/config/instruction_images/st-ten-5/img/rm2.PNG differ diff --git a/config/label_designs/FERRARI/F164F169.nlbl b/config/label_designs/FERRARI/F164F169.nlbl new file mode 100644 index 0000000..cdda43d Binary files /dev/null and b/config/label_designs/FERRARI/F164F169.nlbl differ diff --git a/config/label_designs/STANDARD/EtichettaR5.nlbl b/config/label_designs/STANDARD/EtichettaR5.nlbl index 0769605..5af1648 100644 Binary files a/config/label_designs/STANDARD/EtichettaR5.nlbl and b/config/label_designs/STANDARD/EtichettaR5.nlbl differ diff --git a/config/label_designs/STANDARD/EtichettaR5_Pitesti.nlbl b/config/label_designs/STANDARD/EtichettaR5_Pitesti.nlbl new file mode 100644 index 0000000..6474ee4 Binary files /dev/null and b/config/label_designs/STANDARD/EtichettaR5_Pitesti.nlbl differ diff --git a/config/label_designs/TUBI RISCALDATI/ETA013.btw b/config/label_designs/TUBI RISCALDATI/ETA013.btw index 6f710cf..29fc523 100644 Binary files a/config/label_designs/TUBI RISCALDATI/ETA013.btw and b/config/label_designs/TUBI RISCALDATI/ETA013.btw differ diff --git a/config/label_designs/TUBI RISCALDATI/ETA013_OLD.btw b/config/label_designs/TUBI RISCALDATI/ETA013_OLD.btw new file mode 100644 index 0000000..f905dd1 Binary files /dev/null and b/config/label_designs/TUBI RISCALDATI/ETA013_OLD.btw differ diff --git a/config/label_designs/TUBI RISCALDATI/ETA013_PM.btw b/config/label_designs/TUBI RISCALDATI/ETA013_PM.btw new file mode 100644 index 0000000..f87cc20 Binary files /dev/null and b/config/label_designs/TUBI RISCALDATI/ETA013_PM.btw differ diff --git a/config/label_designs/TUBI RISCALDATI/TEXA.btw b/config/label_designs/TUBI RISCALDATI/TEXA.btw new file mode 100644 index 0000000..5598a83 Binary files /dev/null and b/config/label_designs/TUBI RISCALDATI/TEXA.btw differ diff --git a/config/label_templates/ETA013L.prn b/config/label_templates/ETA013L.prn index 140631d..43172a9 100644 --- a/config/label_templates/ETA013L.prn +++ b/config/label_templates/ETA013L.prn @@ -9,39 +9,39 @@ SET PARTIAL_CUTTER OFF SET TEAR ON CLS CODEPAGE 1252 -TEXT 203,221,"0",180,9,9,"{TSET}s" -TEXT 205,374,"0",180,9,9,"{RESPFILL}mbar" -TEXT 260,792,"0",180,9,9,"{CLIENT}" -TEXT 336,987,"0",180,12,12,"ERRECINQUE" -TEXT 292,923,"0",180,8,8,"Fluid system" -TEXT 307,894,"0",180,8,8,"Via Meucci 31/A" -TEXT 333,865,"0",180,8,8,"10079 Mappano (TO)" -TEXT 375,792,"0",180,9,9,"Cliente:" -TEXT 375,763,"0",180,9,9,"N. disegno:" -TEXT 375,732,"0",180,9,9,"N. dis. R5:" -TEXT 375,702,"0",180,9,9,"N. pezzo:" -TEXT 375,671,"0",180,9,9,"Data/ora prova:" -TEXT 375,640,"0",180,9,9,"{DATETIME}" -TEXT 252,763,"0",180,9,9,"{RECIPE}" -TEXT 222,732,"0",180,9,9,"{PART}" -TEXT 241,702,"0",180,9,9,"{SN}" -BARCODE 384,583,"128M",102,0,180,2,4,"!105{BCODE}" -TEXT 381,374,"0",180,9,9,"P. riempimento:" -TEXT 381,336,"0",180,9,9,"P. assestamento:" -TEXT 381,298,"0",180,9,9,"Caduta:" -TEXT 203,336,"0",180,9,9,"{RESPSET}mbar" -TEXT 203,298,"0",180,9,9,"{RESLEAK}mbar" -TEXT 381,259,"0",180,9,9,"T. riemp:" -TEXT 381,221,"0",180,9,9,"T. stab:" -TEXT 381,182,"0",180,9,9,"T. prova:" -TEXT 204,259,"0",180,9,9,"{TFILL}s" -TEXT 203,182,"0",180,9,9,"{TTEST}s" -TEXT 381,143,"0",180,9,9,"Caduta MAX" -TEXT 381,104,"0",180,9,9,"Press nominale" -TEXT 203,143,"0",180,9,9,"{PMIN}mbar" -TEXT 203,104,"0",180,9,9,"{PTEST}mbar" -TEXT 375,67,"0",180,11,11,"ESITO:" -TEXT 274,67,"0",180,11,11,"{RESULT}" -TEXT 312,450,"0",180,8,8,"{BCODE}" +TEXT 203,232,"0",180,9,9,"{TSET}s" +TEXT 203,386,"0",180,9,9,"{RESPFILL}mbar" +TEXT 292,813,"0",180,9,9,"{CLIENT}" +TEXT 330,990,"0",180,12,12,"ERRECINQUE" +TEXT 292,930,"0",180,8,8,"Fluid system" +TEXT 307,901,"0",180,8,8,"Via Meucci 31/A" +TEXT 333,872,"0",180,8,8,"10079 Mappano (TO)" +TEXT 379,813,"0",180,9,9,"Cliente:" +TEXT 379,778,"0",180,9,9,"N. disegno:" +TEXT 379,736,"0",180,9,9,"N. dis. R5:" +TEXT 379,703,"0",180,9,9,"N. pezzo:" +TEXT 379,667,"0",180,9,9,"Data/ora prova:" +TEXT 379,632,"0",180,9,9,"{DATETIME}" +TEXT 257,778,"0",180,9,9,"{RECIPE}" +TEXT 257,743,"0",180,11,11,"{PART}" +TEXT 257,703,"0",180,9,9,"{SN}" +BARCODE 379,576,"128M",102,0,180,2,4,"!105{BCODE}" +TEXT 379,386,"0",180,9,9,"P. riempimento:" +TEXT 379,348,"0",180,9,9,"P. assestamento:" +TEXT 379,310,"0",180,9,9,"Caduta:" +TEXT 203,348,"0",180,9,9,"{RESPSET}mbar" +TEXT 203,310,"0",180,9,9,"{RESLEAK}mbar" +TEXT 379,271,"0",180,9,9,"T. riemp:" +TEXT 379,232,"0",180,9,9,"T. stab:" +TEXT 379,194,"0",180,9,9,"T. prova:" +TEXT 203,271,"0",180,9,9,"{TFILL}s" +TEXT 203,194,"0",180,9,9,"{TTEST}s" +TEXT 379,155,"0",180,9,9,"Caduta MAX" +TEXT 379,116,"0",180,9,9,"Press nominale" +TEXT 203,155,"0",180,9,9,"{PMIN}mbar" +TEXT 203,116,"0",180,9,9,"{PTEST}mbar" +TEXT 379,67,"0",180,11,11,"ESITO:" +TEXT 285,67,"0",180,11,11,"{RESULT}" +TEXT 379,464,"0",180,9,9,"{BCODE}" PRINT 1,1 \ No newline at end of file diff --git a/config/label_templates/ETA013_DEUTZ.prn b/config/label_templates/ETA013_DEUTZ.prn index fd96f50..072985f 100644 --- a/config/label_templates/ETA013_DEUTZ.prn +++ b/config/label_templates/ETA013_DEUTZ.prn @@ -25,7 +25,7 @@ TEXT 375,617,"0",180,9,9,"{DATETIME}" TEXT 252,766,"0",180,9,9,"{RECIPE}" TEXT 222,709,"0",180,9,9,"{PART}" TEXT 241,678,"0",180,9,9,"{SN}" -BARCODE 384,560,"128M",102,0,180,2,4,"!10500" +BARCODE 384,560,"128M",102,0,180,2,4,"!105{BCODE}" TEXT 381,374,"0",180,9,9,"P. riempimento:" TEXT 381,336,"0",180,9,9,"P. assestamento:" TEXT 381,298,"0",180,9,9,"Caduta:" diff --git a/config/label_templates/ETACL-40_130.prn b/config/label_templates/ETACL-40_130.prn index 3d374dc..e445358 100644 --- a/config/label_templates/ETACL-40_130.prn +++ b/config/label_templates/ETACL-40_130.prn @@ -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 diff --git a/config/label_templates/ETACL.prn b/config/label_templates/ETACL.prn index c610911..e445358 100644 --- a/config/label_templates/ETACL.prn +++ b/config/label_templates/ETACL.prn @@ -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 diff --git a/config/label_templates/EtichettaR5.prn b/config/label_templates/EtichettaR5.prn index cf1999f..fd3080f 100644 --- a/config/label_templates/EtichettaR5.prn +++ b/config/label_templates/EtichettaR5.prn @@ -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 diff --git a/config/label_templates/EtichettaR5_Pitesti.prn b/config/label_templates/EtichettaR5_Pitesti.prn new file mode 100644 index 0000000..7d4787a --- /dev/null +++ b/config/label_templates/EtichettaR5_Pitesti.prn @@ -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 diff --git a/config/label_templates/F164F169.prn b/config/label_templates/F164F169.prn new file mode 100644 index 0000000..dbb6c57 --- /dev/null +++ b/config/label_templates/F164F169.prn @@ -0,0 +1,56 @@ +CT~~CD,~CC^~CT~ +^XA +~TA000 +~JSN +^LT0 +^MNW +^MTT +^PON +^PMN +^LH0,0 +^JMA +^PR2,2 +~SD20 +^JUS +^LRN +^CI27 +^PA0,1,1,0 +^XZ +^XA +^MMT +^PW320 +^LL1119 +^LS0 +^FT27,493^A0N,25,23^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27 +^FT175,493^A0N,25,23^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27 +^FT18,1013^A0N,31,30^FH\^CI28^FDESITO:^FS^CI27 +^FT144,1013^A0N,31,30^FH\^CI28^FDCONFORME^FS^CI27 +^FT29,72^A0N,25,25^FH\^CI28^FDNumero Disegno^FS^CI27 +^FT27,462^A0N,25,25^FH\^CI28^FDData/Ora Prova^FS^CI27 +^FT27,530^A0N,25,25^FH\^CI28^FDStazione: {STATION}^FS^CI27 +^FT27,416^A0N,25,25^FH\^CI28^FDN. Pezzo:^FS^CI27 +^FT135,417^A0N,25,25^FH\^CI28^FD{SN4}^FS^CI27 +^FT27,562^A0N,25,25^FH\^CI28^FDOPERATORE: {BADGE_NUM}^FS^CI27 +^FO52,649^GB215,0,8^FS +^FT19,705^A0N,25,25^FH\^CI28^FDP. prova:^FS^CI27 +^FT19,737^A0N,25,25^FH\^CI28^FDP. rilevata:^FS^CI27 +^FT145,737^A0N,25,25^FH\^CI28^FD{RESPSET}mbar^FS^CI27 +^FT19,764^A0N,25,25^FH\^CI28^FDCaduta ammessa:^FS^CI27 +^FT206,764^A0N,25,25^FH\^CI28^FD{PMIN} mbar^FS^CI27 +^FT19,797^A0N,25,25^FH\^CI28^FDCaduta rilevata:^FS^CI27 +^FT179,797^A0N,25,25^FH\^CI28^FD{RESLEAK} mbar^FS^CI27 +^FT19,908^A0N,25,25^FH\^CI28^FDT.Prova^FS^CI27 +^FT207,912^A0N,25,25^FH\^CI28^FD{TTEST} s^FS^CI27 +^FT18,864^A0N,25,25^FH\^CI28^FDT.Riempim.^FS^CI27 +^FT207,864^A0N,25,25^FH\^CI28^FD{TFILL} s^FS^CI27 +^FT19,886^A0N,25,25^FH\^CI28^FDT.Stabilizzazione^FS^CI27 +^FT207,888^A0N,25,25^FH\^CI28^FD{TSET} s^FS^CI27 +^FT145,705^A0N,25,25^FH\^CI28^FD{PTEST} mbar^FS^CI27 +^FT31,248^BXN,6,200,0,0,1,_,1 +^FH\^FD{PART}{HH}{MI}{JJJ}{YY}^FS +^FT29,108^A0N,25,25^FH\^CI28^FD992752^FS^CI27 +^FT29,287^A0N,25,25^FH\^CI28^FD{PART}{HH}{MI}{JJJ}{YY}^FS^CI27 +^FT27,594^A0N,25,25^FH\^CI28^FDGB16897 / {DD}/{MO}/{YY}^FS^CI27 +^FT27,625^A0N,25,25^FH\^CI28^FDERRECINQUE / 21882^FS^CI27 +^PQ1,0,1,Y +^XZ diff --git a/config/machine_settings/defaults.ini b/config/machine_settings/defaults.ini index 23ac1bd..22004bd 100644 --- a/config/machine_settings/defaults.ini +++ b/config/machine_settings/defaults.ini @@ -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 diff --git a/config/machine_settings/hostnames.ini b/config/machine_settings/hostnames.ini index 664d451..819d1f9 100644 --- a/config/machine_settings/hostnames.ini +++ b/config/machine_settings/hostnames.ini @@ -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 diff --git a/config/machine_settings/st-ten-1.ini b/config/machine_settings/st-ten-1.ini index 5a60b38..c50b795 100644 --- a/config/machine_settings/st-ten-1.ini +++ b/config/machine_settings/st-ten-1.ini @@ -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: 10 +settling_time: 10 +settling_pressure_min_percent: 5 +settling_pressure_max_percent: 5 +test_pressure: 7000 +test_time: 10 +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 \ No newline at end of file diff --git a/config/machine_settings/st-ten-2.ini b/config/machine_settings/st-ten-2.ini index 8639302..621a3ef 100644 --- a/config/machine_settings/st-ten-2.ini +++ b/config/machine_settings/st-ten-2.ini @@ -20,5 +20,38 @@ recipe_name_field: cod finito cliente part_number_field: cod finito r5 barcode_enable_field: verifica_codice_a_barre_abilitata barcode_serial_field: codice_a_barre -label_template_field: modello_etichetta -description_field: cod semilavorato costampato \ No newline at end of file +label_template_field: etichetta +description_field: cod semilavorato costampato + +[recipes_defaults] +prova_tenuta_abilitata: x +warning_img: +tempo_pre_riempimento: 0 +pressione_pre_riempimento: 1000 +tempo_riempimento: 10 +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: 15000 +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 \ No newline at end of file diff --git a/config/machine_settings/st-ten-3.ini b/config/machine_settings/st-ten-3.ini index 33ddd83..8b38ac9 100644 --- a/config/machine_settings/st-ten-3.ini +++ b/config/machine_settings/st-ten-3.ini @@ -24,3 +24,36 @@ barcode_enable_field: verifica_codice_a_barre_abilitata_cl [recipes_defaults] descrizione: +prova_tenuta_abilitata: x +warning_img: +tempo_pre_riempimento: 0 +pressione_pre_riempimento: 1000 +tempo_riempimento: 10 +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: 15000 +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: 10 +settling_time: 10 +settling_pressure_min_percent: 5 +settling_pressure_max_percent: 5 +test_pressure: 7000 +test_time: 10 +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 \ No newline at end of file diff --git a/config/machine_settings/st-ten-4.ini b/config/machine_settings/st-ten-4.ini index ee2b749..b92fc86 100644 --- a/config/machine_settings/st-ten-4.ini +++ b/config/machine_settings/st-ten-4.ini @@ -1,31 +1,79 @@ [machine] -description = ST-TEN-4 - TERMOFORMATURA MAPPANO +description = ST-TEN-4 - REPARTO PREFORMATURA - MAPPANO [hardware_config] archive_synchronizer: present -; galaxy_camera: present -uvc_camera: present +uvc_camera: absent label_printer: present -neo_pixels: present +neo_pixels: absent remote_api: absent tecna_t3: present vision_saver: absent vision: absent -screwdriver: present +screwdriver: absent [tecna_t3] port: COM4 -model: t3l +model: t3p [neo_pixels] port: COM5 +[label_printer] +platform: windows +printer: zd421 + [recipe] recipe_name_field: codice_ricetta part_number_field: codice_prodotto label_template_field: modello_etichetta description_field: descrizione -[label_printer] -platform: windows -printer: zd420 +[recipes_defaults] +dimensione_lotto_abilitata: +tempo_pre_riempimento: 0 +pressione_pre_riempimento: 1000 +tempo_riempimento: 10 +tempo_assestamento: 10 +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: 10 +tempo_assestamento_2: 10 +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: 10 +settling_time: 10 +settling_pressure_min_percent: 5 +settling_pressure_max_percent: 5 +test_pressure: 2000 +test_time: 10 +test_pressure_qpos: 10 #Q+ Upper test leak limit (negative mbar) +test_pressure_qneg: 20 #Q- Lower test leak limit (negative mbar) +test_pressure_tt_qpos: 1 # Q+ Upper test leak limit (tube-tube) (positive mbar) +test_pressure_tt_qneg: 5 # Q- Lower test leak limit (tube-tube) (negative mbar) +flush_time: 1 +flush_pressure: 100 +relay_config: 1 \ No newline at end of file diff --git a/config/machine_settings/st-ten-5.ini b/config/machine_settings/st-ten-5.ini index 25080d8..b9fa4f3 100644 --- a/config/machine_settings/st-ten-5.ini +++ b/config/machine_settings/st-ten-5.ini @@ -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: 8 +test_pressure_qneg: 8 test_pressure: 5000 -test_pressure_max_delta: 5 +test_pressure_qpos: 5 flush_time: 1 flush_pressure: 100 relay_config: 1 \ No newline at end of file diff --git a/config/machine_settings/st-ten-6.ini b/config/machine_settings/st-ten-6.ini index 6fd8e6b..46555b6 100644 --- a/config/machine_settings/st-ten-6.ini +++ b/config/machine_settings/st-ten-6.ini @@ -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 \ No newline at end of file diff --git a/config/machine_settings/st-ten-7.ini b/config/machine_settings/st-ten-7.ini new file mode 100644 index 0000000..db0151d --- /dev/null +++ b/config/machine_settings/st-ten-7.ini @@ -0,0 +1,99 @@ +[machine] +description = ST-TEN-7 SECONDO BANCO IVECO DAILY ELETTRICO + +[hardware_config] +archive_synchronizer: present +uvc_camera: absent +label_printer: present +extra_label_printer: present +remote_api: absent +tecna_t3: present +digital_io: present +barcode_recipe_selection: present +show_instructions: yes + +[tecna_t3] +port: COM4 +model: t3l + +[recipe] +recipe_name_field: codice_ricetta +part_number_field: codice_ricetta +label_template_field: modello_etichetta +description_field: descrizione + +[label_printer] +platform: windows +printer: zd421 + +[extra_label_printer] +platform: windows +printer: xlp504 + + +[digital_io] +id: USB-5862,BID#0 + +[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: 5000 +test_pressure_qpos: 5 +flush_time: 1 +flush_pressure: 100 +relay_config: 1 \ No newline at end of file diff --git a/config/machine_settings/st-ten-8.ini b/config/machine_settings/st-ten-8.ini new file mode 100644 index 0000000..414a720 --- /dev/null +++ b/config/machine_settings/st-ten-8.ini @@ -0,0 +1,87 @@ +[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 +barcode_recipe_selection: present +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: 10 +settling_time: 10 +settling_pressure_min_percent: 5 +settling_pressure_max_percent: 5 +test_pressure: 7000 +test_time: 10 +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 \ No newline at end of file diff --git a/config/machine_settings/vm.ini b/config/machine_settings/vm.ini index 1dd03bb..2378fc0 100644 --- a/config/machine_settings/vm.ini +++ b/config/machine_settings/vm.ini @@ -6,3 +6,8 @@ port: COM4 [neo_pixels] port: COM3 + +[label_printer] +platform: windows +printer: zd420 + diff --git a/config/vision/labels/000952054.pbtxt b/config/vision/labels/000952054.pbtxt new file mode 100644 index 0000000..12fa2ca --- /dev/null +++ b/config/vision/labels/000952054.pbtxt @@ -0,0 +1,10 @@ +item { + id: 1 + name: 'ok' + color: '0x55AA55' +} +item { + id: 2 + name: 'ko' + color: '0xff0000' +} diff --git a/config/vision/labels/labels.pbtxt b/config/vision/labels/labels.pbtxt index 4ab5798..12fa2ca 100644 --- a/config/vision/labels/labels.pbtxt +++ b/config/vision/labels/labels.pbtxt @@ -1,10 +1,10 @@ item { id: 1 - name: 'hs-ok' + name: 'ok' color: '0x55AA55' } item { id: 2 - name: 'hs-ko' + name: 'ko' color: '0xff0000' } diff --git a/config/vision/labels/termorestringente_923578.pbtxt b/config/vision/labels/termorestringente_923578.pbtxt new file mode 100644 index 0000000..4ab5798 --- /dev/null +++ b/config/vision/labels/termorestringente_923578.pbtxt @@ -0,0 +1,10 @@ +item { + id: 1 + name: 'hs-ok' + color: '0x55AA55' +} +item { + id: 2 + name: 'hs-ko' + color: '0xff0000' +} diff --git a/config/vision/recipes/000952054.ini b/config/vision/recipes/000952054.ini new file mode 100644 index 0000000..95003a3 --- /dev/null +++ b/config/vision/recipes/000952054.ini @@ -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 diff --git a/config/vision/recipes/termorestringente_923578.ini b/config/vision/recipes/termorestringente_923578.ini index 861193a..4a05850 100644 --- a/config/vision/recipes/termorestringente_923578.ini +++ b/config/vision/recipes/termorestringente_923578.ini @@ -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 diff --git a/config/warning_images/generic/Img-06.png b/config/warning_images/generic/Img-06.png new file mode 100644 index 0000000..ae1b580 Binary files /dev/null and b/config/warning_images/generic/Img-06.png differ diff --git a/config/warning_images/generic/Img-07.png b/config/warning_images/generic/Img-07.png new file mode 100644 index 0000000..dcccb1d Binary files /dev/null and b/config/warning_images/generic/Img-07.png differ diff --git a/config/warning_images/generic/Img-08.png b/config/warning_images/generic/Img-08.png new file mode 100644 index 0000000..c794040 Binary files /dev/null and b/config/warning_images/generic/Img-08.png differ diff --git a/config/warning_images/generic/Img-09.png b/config/warning_images/generic/Img-09.png new file mode 100644 index 0000000..f66aa5b Binary files /dev/null and b/config/warning_images/generic/Img-09.png differ diff --git a/config/warning_images/generic/Img-10.png b/config/warning_images/generic/Img-10.png new file mode 100644 index 0000000..a8a3ffd Binary files /dev/null and b/config/warning_images/generic/Img-10.png differ diff --git a/config/warning_images/generic/Img-11.png b/config/warning_images/generic/Img-11.png new file mode 100644 index 0000000..0109a3d Binary files /dev/null and b/config/warning_images/generic/Img-11.png differ diff --git a/init_win.bat b/init_win.bat index c7208b9..b266984 100644 --- a/init_win.bat +++ b/init_win.bat @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/runme_custom.sh b/runme_custom.sh deleted file mode 100755 index bd9a5cb..0000000 --- a/runme_custom.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -e -cd "$(dirname "$0")" -source "./venv/bin/activate" || source "./venv/Scripts/activate" || : -python -O "./src/main.py" --no-edgetpu --no-tflite $* diff --git a/runme_noautotest.bat b/runme_noautotest.bat new file mode 100644 index 0000000..0e1d578 --- /dev/null +++ b/runme_noautotest.bat @@ -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 diff --git a/simulate.sh b/simulate.sh index d84e9bf..52c9e61 100755 --- a/simulate.sh +++ b/simulate.sh @@ -16,7 +16,6 @@ python -B -u "./src/main.py" \ --auto-accept-test-admin-permission \ --auto-login-admin \ --auto-select \ ---debugger-workaround \ --no-edgetpu \ --no-gpu \ --panel \ diff --git a/src/components/__init__.py b/src/components/__init__.py index 973d595..af23c5e 100644 --- a/src/components/__init__.py +++ b/src/components/__init__.py @@ -11,6 +11,7 @@ from .tecna_marposs_provaset_t3 import TecnaMarpossProvasetT3 from .tecna_screwdriver import TecnaScrewdriver from .test_component import TestComponent from .usb_586x import USB_586x +from .rfid_pn532 import RFID_PN532 if "--vision" in sys.argv: from .galaxy_camera import GalaxyCamera from .neo_pixels import NeoPixels diff --git a/src/components/component.py b/src/components/component.py index aa6625c..599e8c3 100644 --- a/src/components/component.py +++ b/src/components/component.py @@ -85,6 +85,7 @@ class Component(QObject): """ super().__init__() self.config = config + self.log=logging.getLogger(f"{self.__class__.__name__}") self.name = name if name is not None else str(id(self)) self._threaded = threaded self._period = period diff --git a/src/components/dummies/Automation/BDaq/BDaqApi.py b/src/components/dummies/Automation/BDaq/BDaqApi.py index 7e2f0b1..64ad9a4 100644 --- a/src/components/dummies/Automation/BDaq/BDaqApi.py +++ b/src/components/dummies/Automation/BDaq/BDaqApi.py @@ -10,9 +10,6 @@ if platform.architecture()[0] == '32bit': c_uint64 = c_uint32 -if platform.system().lower() == 'windows': - dll = windll.LoadLibrary(r"biodaq") -else: dll = None diff --git a/src/components/dummies/pymodbus/modbus_client.py b/src/components/dummies/pymodbus/modbus_client.py index 249a428..a79434a 100644 --- a/src/components/dummies/pymodbus/modbus_client.py +++ b/src/components/dummies/pymodbus/modbus_client.py @@ -16,11 +16,11 @@ class ModbusClient: return Readout([0] * count) def write_register(self, register, data, unit=None, **kwargs): - self.log.debug(f"{unit}->{register} ({kwargs}) write: {data}, ", flush=True) + self.log.debug(f"{unit}->{register} ({kwargs}) write: {data}, ") return Readout() def write_registers(self, registers, data, unit=None, **kwargs): - self.log.debug(f"{unit}->{registers} ({kwargs}) write: {data}, ", flush=True) + self.log.debug(f"{unit}->{registers} ({kwargs}) write: {data}, ") return Readout() def close(self): diff --git a/src/components/os_label_printer.py b/src/components/os_label_printer.py index 39d94f0..ccab0a4 100644 --- a/src/components/os_label_printer.py +++ b/src/components/os_label_printer.py @@ -8,7 +8,7 @@ from PyQt5.QtWidgets import QMessageBox from .component import Component -if platform.system() == "Windows": +if platform.system().lower() == "windows": import win32print @@ -43,7 +43,7 @@ class Os_Label_Printer(Component): for key, val in context.items(): key = "{" + key + "}" label_file_contents = label_file_contents.replace(key, val) - if platform.system() == "Windows": + if platform.system().lower() == "windows": try: printer = win32print.OpenPrinter(self.printer) job = win32print.StartDocPrinter(printer, 1, ("label", None, "RAW")) diff --git a/src/components/rfid_pn532.py b/src/components/rfid_pn532.py new file mode 100644 index 0000000..86b03d0 --- /dev/null +++ b/src/components/rfid_pn532.py @@ -0,0 +1,80 @@ +import copy +import ctypes +import sys +import platform +from PyQt5.QtCore import QMutex, Qt, QTimer, pyqtSlot, pyqtSignal +from .component import Component +import ndef +import nfc +from nfc.clf import RemoteTarget + + + + +class RFID_PN532(Component): + new_id_signal = pyqtSignal(str) + 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.data_to_write = None + self.mutex = QMutex() + self.simulate="--sim-rfid" in sys.argv + self.clf = None + self.connected=False + self.tag_present=False + self.current_data=None + self.is_win = platform.system().lower() == "windows" + self.dev_list = [f"{self.config['fixture_rfid']['port']}:pn532"] if self.is_win else ['tty:USB0:pn532','tty:USB1:pn532'] + self._period = 1 + + def open_device(self): + self.clf = nfc.ContactlessFrontend() + for dev in self.dev_list: + self.connected = self.clf.open(dev) + if self.connected: + self.log.info(f"CONNECTED TO {dev}") + break + else: + self.log.info(f"UNABLE TO CONNECT TO {dev}") + + def close_device(self): + self.clf.close() + + @pyqtSlot() + def start(self): + super().start() + + @pyqtSlot() + def _get(self): + if self.mutex.tryLock(): + try: + if not self.connected: + self.open_device() + else: + target = self.clf.sense(RemoteTarget('106A'), RemoteTarget('106B'), RemoteTarget('212F')) + if target is not None: + tag = nfc.tag.activate(self.clf, target) + if tag is not None: + self.log.debug("tag present") + if tag.ndef is not None: + tag_content=tag.ndef.records[0].text + if tag_content!=self.current_data: + self.log.info(f"new tag detected:{tag_content}") + self.current_data=tag_content + self.new_id_signal.emit(self.current_data) + else: + self.log.error("tag is not NDEF") + else: + if self.current_data: + self.log.info(f"tag removed:{self.current_data}") + self.current_data = None + self.new_id_signal.emit(None) + self.log.debug("no target present") + + except Exception as e: + self.log.info(f"{e}") + self.connected = False + finally: + self.mutex.unlock() + + def write_tag(self,data): + self.data_to_write=copy.deepcopy(data) diff --git a/src/components/tecna_marposs_provaset_t3.py b/src/components/tecna_marposs_provaset_t3.py index 6276e20..748c23a 100644 --- a/src/components/tecna_marposs_provaset_t3.py +++ b/src/components/tecna_marposs_provaset_t3.py @@ -24,7 +24,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): elif self.model == "t3l": self.registers = t3l_registers else: - raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.") + raise NotImplementedError(f"tecna t3 model {self.model!r} not implemented.") self.set_measure_units() self.units = self.get_measure_units() self.max_program_number = self.read("Max number of programs") @@ -67,7 +67,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): }.items(): self.write(register, unit) # (decimals << 8) + unit) else: - raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.") + raise NotImplementedError(f"tecna t3 model {self.model!r} not implemented.") def get_measure_units(self): units = {} @@ -105,7 +105,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): for unit_name in unit_names: units[unit_name] = unit_spec else: - raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.") + raise NotImplementedError(f"tecna t3 model {self.model!r} not implemented.") return units def _convert_from_format(self, data, formatting=None, decoding_map=None): @@ -222,9 +222,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 +254,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 +280,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 ["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,11 +289,13 @@ 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"], + "PSQ - Next sequence program PSOUT mode": 0, + } if self.model == "t3p": pass @@ -300,7 +306,7 @@ class TecnaMarpossProvasetT3(ModbusComponent): "Pn - Nominal test pressure": step.spec["test_pressure"], }) else: - raise NotImplementedError(f"techna t3 model {self.model!r} not implemented.") + raise NotImplementedError(f"tecna t3 model {self.model!r} not implemented.") self.log.debug(str(spec)) for register, value in spec.items(): self.write(register, value) diff --git a/src/components/tecna_marposs_provaset_t3l_registers.py b/src/components/tecna_marposs_provaset_t3l_registers.py index cf0bb3f..77c0edf 100644 --- a/src/components/tecna_marposs_provaset_t3l_registers.py +++ b/src/components/tecna_marposs_provaset_t3l_registers.py @@ -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", @@ -337,5 +337,5 @@ registers = { "T1 Steps - T1 Step %": [753 - 1, {"dt": "16bit_uint", }], # | 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0 | # | Step % T1 | T1 Steps | - "Sequence": [754 - 1, {"dt": "16bit_uint", }], + "PSQ - Next sequence program PSOUT mode": [754 - 1, {"dt": "16bit_uint", }], } diff --git a/src/components/tecna_marposs_provaset_t3p_registers.py b/src/components/tecna_marposs_provaset_t3p_registers.py index 62a2535..750e8bb 100644 --- a/src/components/tecna_marposs_provaset_t3p_registers.py +++ b/src/components/tecna_marposs_provaset_t3p_registers.py @@ -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", diff --git a/src/components/usb_586x.py b/src/components/usb_586x.py index 2236480..a5cadee 100644 --- a/src/components/usb_586x.py +++ b/src/components/usb_586x.py @@ -8,7 +8,7 @@ from PyQt5.QtCore import QMutex, Qt, QTimer, pyqtSlot, pyqtSignal from .component import Component -is_win = platform.system() == "Windows" +is_win = platform.system().lower() == "windows" if "--sim-io" not in sys.argv: if is_win: @@ -158,7 +158,7 @@ class USB_586x(Component): read = [] if is_win or self.simulate: if self.simulate: - read.append(bytearray(0)) + read=[1,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0] else: ret = self.di_read(0, self.in_size) if ret[0].value == ErrorCode.Success.value: diff --git a/src/components/vision.py b/src/components/vision.py index 5f0bc65..bd4a9cb 100644 --- a/src/components/vision.py +++ b/src/components/vision.py @@ -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} diff --git a/src/components/vision_saver.py b/src/components/vision_saver.py index 0dc8fdc..aff434d 100755 --- a/src/components/vision_saver.py +++ b/src/components/vision_saver.py @@ -37,6 +37,8 @@ class VisionSaver(Component): save_time = int(save_time) if type(save_time) is int: save_time = datetime.fromtimestamp(save_time) + if type(save_time) is str: + save_time = datetime.now() if type(save_time) is not datetime: raise ValueError(f"save_time must be float int or datetime, not {type(save_time)}") timestamp = save_time.strftime(self.time_format) diff --git a/src/lib/db/__init__.py b/src/lib/db/__init__.py index fcf7ce0..fb0510d 100644 --- a/src/lib/db/__init__.py +++ b/src/lib/db/__init__.py @@ -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(): diff --git a/src/lib/db/models/archive.py b/src/lib/db/models/archive.py index 32e1e7d..1aae510 100644 --- a/src/lib/db/models/archive.py +++ b/src/lib/db/models/archive.py @@ -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, diff --git a/src/lib/db/models/users.py b/src/lib/db/models/users.py index 2eae003..ad3423d 100755 --- a/src/lib/db/models/users.py +++ b/src/lib/db/models/users.py @@ -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): diff --git a/src/lib/helpers/config_reader.py b/src/lib/helpers/config_reader.py index f248296..61d39ad 100644 --- a/src/lib/helpers/config_reader.py +++ b/src/lib/helpers/config_reader.py @@ -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.") diff --git a/src/lib/helpers/timing.py b/src/lib/helpers/timing.py index cae4c92..742b766 100644 --- a/src/lib/helpers/timing.py +++ b/src/lib/helpers/timing.py @@ -1,7 +1,7 @@ from time import perf_counter, time ref = time() - perf_counter() - +pass def timing(): global ref diff --git a/src/main.py b/src/main.py index 1030df4..050d9ba 100644 --- a/src/main.py +++ b/src/main.py @@ -11,6 +11,7 @@ import weakref from datetime import datetime from pathlib import Path + if platform.system().lower() == "windows": sys.path.append(f"{os.getcwd()}\src\components") else: @@ -43,7 +44,7 @@ logging.basicConfig( format="{asctime}:{name}:{levelname}:{message}", datefmt="%Y-%m-%dT%H-%M-%S%z", style="{", - level="INFO", + level="DEBUG" if "--debug" in sys.argv else "INFO", handlers=[ logging.StreamHandler(stream=sys.stderr), logging.FileHandler( @@ -63,12 +64,13 @@ try: # IMPORT PROJECT ONLY AFTER SETTING UP SIGNAL, FAULTHANDLER AND LOGGHING from components import (ArchiveSynchronizer, Multicomp730424, Os_Label_Printer, RemoteAPI, - TecnaMarpossProvasetT3, TecnaScrewdriver, USB_586x) + TecnaMarpossProvasetT3, TecnaScrewdriver, USB_586x,RFID_PN532) from lib.db import Users 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, \ + Barcode_Recipe_Selection if "--vision" in sys.argv: from components import GalaxyCamera, NeoPixels, UVCCamera, Vision, VisionSaver @@ -101,7 +103,8 @@ try: "remote_api": {"c": RemoteAPI, "k": {"main": self}}, "screwdriver": {"c": TecnaScrewdriver, "k": {"paused": True}}, "tecna_t3": {"c": TecnaMarpossProvasetT3, "k": {"paused": True}}, - "digital_io":{"c":USB_586x,"k":{"paused":True}} + "digital_io":{"c":USB_586x,"k":{"paused":True}}, + "fixture_id":{"c":RFID_PN532,"k":{"paused":False, "lazy":False}}, } # VISION COMPONENT IS OPTIONAL AND DISABLED BY DEFAULT if "--vision" in sys.argv: @@ -146,15 +149,18 @@ try: logging.exception(traceback.format_exc()) QMessageBox.critical(None, "Errore", f"Errore di avvio del programma di collaudo:\n\n{e}") quit() + # connect camera frames to vision if "vision" in self.components and "uvc_camera" in self.components: self.components["vision"].set_sources({"uvc_camera": self.components["uvc_camera"].out}) elif "vision" in self.components and "galaxy_camera" in self.components: self.components["vision"].set_sources({"galaxy_camera": self.components["galaxy_camera"].out}) + # connect tecna to screwdriver if "screwdriver" in self.components and "tecna_t3" in self.components: self.components["tecna_t3"].set_requestors({"screwdriver": self.components["screwdriver"].request}) self.components["screwdriver"].set_sources({"tecna_t3": self.components["tecna_t3"].out}) + # GUI INIT if "--no-gui" not in sys.argv: # self.main_window = Main_Window(self.bench) @@ -166,23 +172,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 +197,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 +224,26 @@ 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)) + self.main_window.centralWidget().request_autotest("login") 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() + #Users.logout() self.main_window.admin_m.menuAction().setVisible(False) - self.open_login() + if type(self.main_window.centralWidget().centralWidget.widget) in (Recipe_Selection,Barcode_Recipe_Selection): + # LOGOUT IMMEDIATELY IF NOT TESTING + Users.logout() + self.open_login() + else: + if not self.main_window.centralWidget().autotesting: + # LOGOUT AFTER AUTOTEST IF TESTING + self.main_window.centralWidget().request_autotest("logout") + else: + # LOGOUT IMMEDIATELY IF AUTOTESTING + Users.logout() + self.open_login() def set_recipe_mode_table(self): self.main_window.centralWidget().set_recipe_mode_table() diff --git a/src/requirements.txt b/src/requirements.txt index f52bf05..2ad5bfc 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -4,6 +4,7 @@ bottle google-cloud-storage imutils lxml +nfcpy numpy opencv-python-headless peewee diff --git a/src/scripts/csv_extract_LEAK.py b/src/scripts/csv_extract_LEAK.py new file mode 100644 index 0000000..30d7a8d --- /dev/null +++ b/src/scripts/csv_extract_LEAK.py @@ -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.') \ No newline at end of file diff --git a/src/scripts/fix_db_qpos_qneg.sqlite b/src/scripts/fix_db_qpos_qneg.sqlite new file mode 100644 index 0000000..d8afd95 --- /dev/null +++ b/src/scripts/fix_db_qpos_qneg.sqlite @@ -0,0 +1,5 @@ +-- REMEMBER TO BACKUP DB FIRST -- +update steps set spec = json_insert(spec,"$.test_pressure_qpos",(json_extract(steps.spec, '$.test_pressure_max_delta'))) where type == "leak_1" or type=="leak_2"; +update steps set spec = json_insert(spec,"$.test_pressure_qneg",(json_extract(steps.spec, '$.test_pressure_min_delta'))) where type == "leak_1" or type=="leak_2"; +update steps set spec = json_insert(spec,"$.test_pressure_qpos",(json_extract(steps.spec, '$.test_pressure_max_delta'))) where type == "leak_1" or type=="leak_2"; +update steps set spec = json_insert(spec,"$.test_pressure_qneg",(json_extract(steps.spec, '$.test_pressure_min_delta'))) where type == "leak_1" or type=="leak_2"; diff --git a/src/scripts/old_recipe_to_csv.py b/src/scripts/old_recipe_to_csv.py index 3bd3c73..6feecaf 100644 --- a/src/scripts/old_recipe_to_csv.py +++ b/src/scripts/old_recipe_to_csv.py @@ -8,13 +8,19 @@ fieldnames = [ "cliente", "codice_prodotto", "descrizione", - "prova_tenuta_abilitata_2" + "pressione_di_test", + "pressione_di_test_delta_minimo", + "pressione_di_test_delta_massimo", + "tempo_riempimento", + "tempo_assestamento", + "tempo_di_test", + #"prova_tenuta_abilitata_2" ] # FOLDER CONFIGURATION in_path="../../tmp/ricette/" files=glob(f"{in_path}/**/*.dsg",recursive=True) -csv_path="../test/csv_import/importazione da banco montaggio.csv" +csv_path="../test/csv_import/importazione da banco preformatura.csv" data=[] #FOR EACH FILE CREATE A TEST RECIPE @@ -30,7 +36,13 @@ for file in files: "cliente":list(read_values["cliente"].keys())[0], "codice_prodotto":list(read_values["numero disegno"].keys())[0], "descrizione":os.path.basename(file), - "prova_tenuta_abilitata_2":"x" if list(read_values["prova2:tempo di riempimento"].keys())[0] not in ("0","00") else "" + "pressione_di_test":str(int(list(read_values["prova2:pressione di test"].keys())[0])*10), + "pressione_di_test_delta_minimo":list(read_values["prova2:tolleranza"].keys())[0], + "pressione_di_test_delta_massimo":list(read_values["prova2:tolleranza"].keys())[0], + "tempo_riempimento":list(read_values["prova2:tempo di riempimento"].keys())[0], + "tempo_assestamento":list(read_values["prova2:tempo di stabilizzazione"].keys())[0], + "tempo_di_test": list(read_values["prova2:tempo di prova"].keys())[0], + #"prova_tenuta_abilitata_2":"x" if list(read_values["prova2:tempo di riempimento"].keys())[0] not in ("0","00") else "" } data.append(line) diff --git a/src/test/csv_import/Tabella_e_daily_p3.csv b/src/test/csv_import/Tabella_e_daily_p3.csv new file mode 100644 index 0000000..186549c --- /dev/null +++ b/src/test/csv_import/Tabella_e_daily_p3.csv @@ -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,,,, diff --git a/src/test/csv_import/importazione da banco preformatura.csv b/src/test/csv_import/importazione da banco preformatura.csv new file mode 100644 index 0000000..9449504 --- /dev/null +++ b/src/test/csv_import/importazione da banco preformatura.csv @@ -0,0 +1,165 @@ +codice_ricetta,cliente,codice_prodotto,descrizione,pressione_di_test,pressione_di_test_delta_minimo,pressione_di_test_delta_massimo,tempo_riempimento,tempo_assestamento,tempo_di_test +5802011947,fpt,5802011947,5802011947.dsg,2000,10,10,10,10,10 +5801970021,lancia bolzano,5801970021,5801970021.dsg,8000,10,10,10,10,10 +5802401058,FPT,5802401058,5802401058.dsg,2000,10,10,05,20,10 +579970919,iveco magirus,579970919,579970919.dsg,8000,20,20,10,10,10 +5801404429,fpt,5801404429,5801404429.dsg,2000,10,10,10,10,10 +5802108501,bolzano,5802108501,5802108501.dsg,8000,10,10,10,10,10 +5801871355,fpt,5801871355,test sonda 6 (2).dsg,2000,10,10,10,10,10 +5802195437,fpt,5802195437,5802195437.dsg,2000,10,10,10,10,10 +5802990922,cnh,5802990922,5802990922.dsg,10000,30,30,5,5,10 +5802754975,fpt,5802754975,5802754975.dsg,6000,30,30,10,10,10 +5802506048,fpt,5802506048,5802506048.dsg,2000,20,20,10,20,40 +5802772050,IVECO,5802772050,5802772050.dsg,10000,20,20,10,20,10 +5802401142,FPT,5802401142,5802401142.dsg,2000,10,10,10,10,10 +5801684362,fpt,5801684362,5801684362.dsg,2000,10,10,10,10,10 +5802362033,fpt,5802362033,5802362033.dsg,2000,10,10,10,10,10 +5801684373,fpt,5801684373,5801684373.dsg,2000,10,10,10,10,10 +5801592607,fpt,5801592607,5801592607.dsg,2000,10,10,10,10,10 +8051475,fpt,8051475,8051475.dsg,2000,10,10,10,10,10 +5801779216,fpt,5801779216,5801779216.dsg,6000,30,30,05,05,20 +5802731910,lancia bolzano,5802731910,5802731910.dsg,8000,10,10,10,10,10 +5802108503,bolzano,5802108503,5802108503.dsg,8000,10,10,10,10,10 +5801869611,fpt,5801869611,5801869611.dsg,6000,30,30,05,05,20 +504291549,bolzano,504291549,504291549.dsg,8000,10,10,10,10,10 +16L0001CP,fpt,16L0001CP,16L0001CP mc laren.dsg,1000,10,10,10,10,10 +504354068,fpt,504354068,504354068.dsg,2000,10,10,10,10,10 +5801588455,fpt,5801588455,5801588455.dsg,2000,10,10,10,10,10 +5802517329,fpt,5802517329,5802517329.dsg,2000,30,30,05,10,10 +5802899148,fpt,5802899148,5802899148.dsg,2000,10,10,10,20,99 +5803012719,cnh,5803012719,5803012719.dsg,10000,30,30,5,5,10 +TGA001EL,VANHOOL,TGA001EL,TGA001EL.dsg,120000,30,30,10,15,10 +5801667698,fpt,5801667698,5801667698.dsg,2000,10,10,10,10,10 +5802011985,fpt,5802011985,5802011985.dsg,2000,10,10,10,10,10 +504126998,bolzano,504126998,504126998.dsg,8000,10,10,10,10,10 +5801636013,fpt,5801636013,5801636013.dsg,2000,10,10,10,10,10 +5802200725,CNH,5802200725,5802200725.dsg,3000,30,30,10,10,40 +504049840,lancia bolzano,504049840,504049840.dsg,8000,10,10,10,10,10 +5801970066,bolzano,5801970066,5801970066.dsg,8000,10,10,10,10,10 +5802093875,FPT,5802093875,5802093875.dsg,2000,10,10,10,10,10 +5801368939,fpt,5801368939,5801368939.dsg,2000,10,10,10,10,10 +5802195441,fpt,5802195441,5802195441.dsg,2000,10,10,10,10,10 +003934,dts,003934,003934.dsg,2000,10,10,10,10,10 +5802093832,FPT,5802093832,5802093832.dsg,2000,10,10,10,10,10 +5802422752,fpt,5802422752,5802422752.dsg,2000,10,10,05,20,10 +5801632026,FPT,5801632026,5801632026.dsg,2000,10,10,10,10,10 +5801404445,fpt,5801404445,5801404445.dsg,2000,10,10,10,10,10 +5801970064,bolzano,5801970064,5801970064.dsg,8000,10,10,10,10,10 +5801615767,irisbus,5801615767,5801615767.dsg,10000,10,10,10,10,10 +5006217212,IVECO CDR,5006217212,5006217212 IVECO CDR.dsg,10000,20,20,10,10,10 +5801664502,fpt,5801664502,5801664502.dsg,2000,10,10,10,10,07 +5801871355,fpt,5801871355,TEST.dsg,2000,10,10,10,10,10 +5802457210,heuliez bus,5802457210,5802457210.dsg,10000,10,10,10,10,10 +5801541811,fpt,5801541811,5801541811.dsg,2000,10,10,10,10,10 +5802011990,fpt,5802011990,5802011990.dsg,2000,10,10,10,10,10 +5801970067,bolzano,5801970067,5801970067.dsg,8000,10,10,10,10,10 +5802772051,IVECO,5802772051,5802772051.dsg,10000,20,20,10,20,10 +5802832212,fpt,5802832212,5802832212.dsg,2000,10,10,10,20,40 +504354067,fpt,504354067,504354067.dsg,2000,10,10,10,10,10 +5801565620,fpt,5801565620,5801565620.dsg,2000,10,10,10,10,10 +5801565599,fpt,5801565599,5801565599.dsg,2000,10,10,10,10,10 +5803012724,cnh,5803012724,5803012724.dsg,10000,30,30,5,5,10 +504321531,bolzano,504321531,504321531.dsg,8000,10,10,10,10,10 +5802771992,IVECO,5802771992,5802771992.dsg,10000,20,20,05,10,10 +5802753762,fpt,5802753762,5802753762.dsg,2000,10,10,10,20,60 +5802729983,lancia bolzano,5802729983,5802729983.dsg,8000,10,10,10,10,10 +5801592617,fpt,5801592617,5801592617.dsg,2000,10,10,10,10,10 +5801501533,fpt,5801501533,5801501533.dsg,2000,10,10,10,10,10 +579970920,iveco magirus,579970920,579970920.dsg,8000,20,20,10,10,10 +5801869610,fpt,5801869610,5801869610.dsg,6000,30,30,05,05,20 +5801666343,fpt,5801666343,5801666343.dsg,2000,10,10,10,10,10 +5801616061,irisbus,5801616061,5801616061.dsg,10000,10,10,10,10,10 +5006217211,IVECO CDR,5006217211,5006217211 IVECO CDR.dsg,10000,20,20,10,10,10 +5802362019,fpt,5802362019,5802362019.dsg,2000,10,10,10,10,10 +504385052,fpt,504385052,504385052.dsg,10000,10,10,10,10,10 +5802991065,cnh,5802991065,5802991065.dsg,10000,30,30,5,5,10 +5801821750,fpt,5801821750,5801821750.dsg,2000,10,10,10,10,10 +5802282454,fpt,5802282454,5802282454.dsg,2000,10,10,10,20,20 +5802771977,IVECO,5802771977,5802771977.dsg,10000,20,20,05,10,10 +5801970018,lancia bolzano,5801970018,5801970018.dsg,8000,10,10,10,10,10 +60192054,lancia,60192054,60192054.dsg,8000,10,10,10,10,10 +5802991066,cnh,5802991066,5802991066.dsg,10000,30,30,5,5,10 +5801384839,lancia bolzano,5801384839,5801384839.dsg,8000,10,10,10,10,10 +5801384838,lancia bolzano,5801384838,5801384838.dsg,8000,10,10,10,10,10 +5802912912,fpt,5802912912,5802912912.dsg,2000,10,10,10,20,60 +5802399858,fpt,5802399858,5802399858.dsg,2000,10,10,05,20,10 +5801615766,irisbus,5801615766,5801615766.dsg,10000,10,10,10,10,10 +5801636018,fpt,5801636018,5801636018.dsg,2000,10,10,10,10,10 +5802170804,bolzano,5802170804,5802170804.dsg,8000,10,10,10,10,10 +5802459861,lancia bolzano,5802459861,5802459861.dsg,3000,10,10,05,25,10 +5801744070,fpt,5801744070,5801744070.dsg,2000,10,10,10,10,10 +504354065,fpt,504354065,504354065.dsg,2000,10,10,10,10,10 +5801429438,fpt,5801429438,5801429438.dsg,3000,10,10,10,10,10 +5801501538,fpt,5801501538,5801501538.dsg,2000,10,10,10,10,10 +5801871355,fpt,5801871355,5801871355.dsg,2000,10,10,10,10,10 +5802912988,fpt,5802912988,5802912988.dsg,2000,10,10,10,20,70 +579970907,iveco magirus,579970907,579970907.dsg,8000,20,20,10,10,10 +5802901208,fpt,5802901208,FPT_5802901208.dsg,3000,30,30,05,25,10 +5802399842,fpt,5802399842,5802399842.dsg,2000,10,10,10,20,57 +5801744059,fpt,5801744059,5801744059.dsg,2000,10,10,10,10,10 +5801779215,fpt,5801779215,5801779215.dsg,6000,30,30,05,05,20 +504321532,lancia bolzano,504321532,504321532.dsg,8000,10,10,10,10,10 +5802518329,fpt,5802518329,5802518329.dsg,2000,10,10,05,20,10 +5801404450,fpt,5801404450,5801404450.dsg,10000,30,30,30,30,10 +5801384841,lqncia bolzano,5801384841,5801384841.dsg,8000,10,10,10,10,10 +5801384842,lancia bolzano,5801384842,5801384842.dsg,8000,10,10,10,10,10 +504378974,fpt,504378974,504378974.dsg,5000,30,30,10,10,15 +5802912853,fpt,5802912853,5802912853.dsg,2000,10,10,05,20,120 +5801588464,fpt,5801588464,5801588464.dsg,2000,10,10,10,10,10 +60192056,lancia bolzano,60192056,60192056.dsg,8000,10,10,10,10,10 +5801770912,fpt,5801770912,5801770912.dsg,2000,10,10,10,10,10 +5801780088,fpt,5801780088,5801780088.dsg,6000,30,30,05,05,20 +test sonda 6,fpt,test sonda 6,Test controllo sonda n° 6.dsg,2000,10,10,10,10,10 +5006217210,IVECO CDR,5006217210,5006217210 IVECO CDR.dsg,10000,10,10,10,10,10 +5802011955,fpt,5802011955,5802011955.dsg,2000,10,10,10,10,10 +5802506033,fpt,5802506033,5802506033.dsg,2000,20,20,10,20,30 +5802195448,fpt,5802195448,5802195448.dsg,2000,10,10,10,10,10 +5802170779,bolzano,5802170779,5802170779.dsg,8000,10,10,10,10,10 +5801869604,fpt,5801869604,5801869604.dsg,6000,30,30,05,05,20 +001030,dts,001030,001030.dsg,5000,10,10,10,30,30 +5802782344,IVECO,5802782344,5802782344.dsg,5000,10,10,10,10,10 +5802784037,IVECO,5802784037,5802784037.dsg,5000,10,10,10,10,10 +5801615768,irisbus,5801615768,5801615768.dsg,10000,10,10,10,10,10 +504354070,fpt,504354070,504354070.dsg,2000,10,10,10,10,10 +5802401073,FPT,5802401073,5802401073.dsg,2000,10,10,05,20,10 +5801912552,fpt,5801912552,5801912552.dsg,6000,30,30,05,05,20 +5801524941,fpt,5801524941,5801524941.dsg,10000,30,30,10,30,30 +5802753755,fpt,5802753755,5802753755.dsg,2000,10,10,10,20,60 +5802930104,fpt,5802930104,5802930104.dsg,2000,10,10,05,20,120 +5801613010,fpt,5801613010,5801613010.dsg,2000,10,10,10,10,10 +5801603399,fpt,5801603399,5801603399.dsg,2000,10,10,10,10,10 +5801925887,fpt,5801925887,5801925887.dsg,3000,10,10,10,10,10 +5802990926,cnh,5802990926,5802990926.dsg,10000,30,30,5,5,10 +5801576299,fpt,5801576299,5801576299.dsg,2000,10,10,10,10,10 +011356,dts,011356,011356.dsg,5000,10,10,10,30,30 +5802269836,fpt,5802269836,5802269836.dsg,2000,30,30,05,10,10 +504049844,lancia bolzano,504049844,504049844.dsg,8000,10,10,10,10,10 +5801378904,fpt,5801378904,5801378904.dsg,2000,10,10,10,10,10 +5801970019,lancia bolzano,5801970019,5801970019.dsg,8000,10,10,10,10,10 +5802965967,fpt,5802965967,5802965967.dsg,2000,10,10,10,20,99 +5802832205,fpt,5802832205,5802832205.dsg,2000,10,10,10,20,40 +579970916,iveco magirus,579970916,579970916.dsg,8000,20,20,10,10,10 +5802889710,IVECO BUS,5802889710,5802889710.dsg,15000,15,15,10,30,50 +5802506036,fpt,5802506036,5802506036.dsg,2000,20,20,10,20,20 +5801429431,fpt,5801429431,5801429431.dsg,3000,10,10,10,10,20 +5801869609,fpt,5801869609,5801869609.dsg,6000,30,30,5,5,20 +5802425718,FPT,5802425718,5802425718.dsg,2000,10,10,10,20,20 +5802425688,fpt,5802425688,5802425688.dsg,2000,10,10,10,20,45 +504326641,lancia boolzano,504326641,504326641.dsg,8000,10,10,10,10,10 +5801780089,fpt,5801780089,5801780089.dsg,6000,30,30,05,05,20 +504365800,fpt,504365800,504365800.dsg,2000,10,10,10,10,10 +504291548,bolzano,504291548,504291548.dsg,8000,10,10,10,10,10 +5802195453,fpt,5802195453,5802195453.dsg,2000,10,10,10,10,10 +5801429403,fpt,5801429403,5801429403.dsg,3000,10,10,10,10,10 +5801384840,lancia bolzano,5801384840,5801384840.dsg,8000,10,10,10,10,10 +504126777,bolzano,504126777,504126777.dsg,8000,10,10,10,10,10 +5801862227,lbz,5801862227,5801862227.dsg,8000,10,10,10,10,10 +5801368948,fpt,5801368948,5801368948.dsg,2000,10,10,10,10,10 +5801565573,fpt,5801565573,5801565573.dsg,2000,10,10,10,10,10 +5801743988,fpt,5801743988,5801743988.dsg,2000,10,10,10,10,10 +5801923370,fpt,5801923370,5801923370.dsg,2000,10,10,10,10,10 +5801743980,fpt,5801743980,5801743980.dsg,2000,10,10,10,10,10 +MY83-6B747-BA,ASTON MARTIN,MY83-6B747-BA,MY83-6B747-BA.dsg,7000,20,20,05,05,30 +MY83-6B748-BA,ASTON MARTIN,MY83-6B748-BA,MY83-6B748-BA.dsg,7000,20,20,05,05,30 +MY83-6L694-AB,ASTON MARTIN,MY83-6L694-AB,MY83-6L694-AB.dsg,7000,20,20,05,05,30 +MY83-6L701-AB,ASTON MARTIN,MY83-6L701-AB,MY83-6L701-AB.dsg,7000,20,20,05,05,30 diff --git a/src/test/csv_import/test_import_himatic my24.csv b/src/test/csv_import/test_import_himatic my24.csv new file mode 100644 index 0000000..acf0c77 --- /dev/null +++ b/src/test/csv_import/test_import_himatic my24.csv @@ -0,0 +1,13 @@ +codice_ricetta,cliente,codice_prodotto,descrizione,avvitatura_abilitata,viti,prova_tenuta_abilitata,tempo_riempimento,tempo_assestamento,percentuale_minima_pressione_assestamento,percentuale_massima_pressione_assestamento,tempo_di_test,pressione_di_test_delta_minimo,pressione_di_test,pressione_di_test_delta_massimo,tempo_svuotamento,pressione_svuotamento,stampa_etichetta_abilitata,modello_etichetta +5803148257,IVECO,5803148257,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148256,IVECO,5803148256,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148263,IVECO,5803148263,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148261,IVECO,5803148261,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148264,IVECO,5803148264,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148265,IVECO,5803148265,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148267,IVECO,5803148267,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148266,IVECO,5803148266,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803166717,IVECO,5803166717,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148269,IVECO,5803148269,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803148268,IVECO,5803148268,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn +5803167128,IVECO,5803167128,Daily Himatic MY24,,,x,5,5,10,10,5,30,5000,30,1,100,x,ETA30x16.prn diff --git a/src/test/label_printer.py b/src/test/label_printer.py index 4d490b8..9c2d22c 100644 --- a/src/test/label_printer.py +++ b/src/test/label_printer.py @@ -5,15 +5,42 @@ from PyQt5.QtWidgets import QApplication from components import Os_Label_Printer from lib.helpers import ConfigReader -config = ConfigReader(system_id="stten5") - -dmtx="5802850925" +config = ConfigReader(system_id="vm") +time =datetime.now() context = { - "PART": dmtx, - "SN5": str(12345), - "DATE": datetime.now().strftime("%d/%m/%Y"), - "TIME": datetime.now().strftime("%H:%M:%S"), + # RECIPE DATA + "RECIPE": "000992752", + "PART": "000992752", + "TFILL": "5", + "TSET": "10", + "TTEST": "10", + "PSETMINP_A": "4750", + "PSETMAXP_A": "5250", + "PTEST": "5000", + "PMIN": "30", + "RESPSET": "5123", + "RESLEAK": "12.34", + "SN4": "1234", + # TIME DEFINITION + "DATETIME": time.strftime("%d/%m/%Y %H:%M:%S"), + "DATE": time.strftime("%d/%m/%Y"), + "TIME": time.strftime("%H:%M:%S"), + "YYYY": time.strftime("%Y"), + "YY": time.strftime("%y"), + "MO": time.strftime("%m"), + "DD": time.strftime("%d"), + "HH": time.strftime("%H"), + "MI": time.strftime("%M"), + "SS": time.strftime("%S"), + "JJJ": time.strftime("%j"), + # EXTRA DATA + "SHIFT": "1", + "STATION": "ST-TEN-1", + "OPERATOR": "MARIO", + "BADGE_NUM": "999", + } + app = QApplication(sys.argv) if "--extra" in sys.argv: @@ -25,4 +52,4 @@ else: # TEST STANDARD PRINTER printer = Os_Label_Printer(config=config, name="label_printer") printer.config_changed() - printer.print_label("ETA30x16.prn", context=context) + printer.print_label("F164F169.prn", context=context) diff --git a/src/test/label_printer_edaily.py b/src/test/label_printer_edaily.py new file mode 100644 index 0000000..e8205aa --- /dev/null +++ b/src/test/label_printer_edaily.py @@ -0,0 +1,55 @@ +import sys +from datetime import datetime +from PyQt5.QtWidgets import QApplication + +from components import Os_Label_Printer +from lib.helpers import ConfigReader + +config = ConfigReader(system_id="st-ten-7") +time =datetime.now() +context = { + # RECIPE DATA + "RECIPE": "5803037204", + "PART": "5803037204", + "TFILL": "5", + "TSET": "10", + "TTEST": "10", + "PSETMINP_A": "4750", + "PSETMAXP_A": "5250", + "PTEST": "5000", + "PMIN": "30", + "RESPSET": "5123", + "RESLEAK": "12.34", + "SN5": "12345", + # TIME DEFINITION + "DATETIME": time.strftime("%d/%m/%Y %H:%M:%S"), + "DATE": time.strftime("%d/%m/%Y"), + "TIME": time.strftime("%H:%M:%S"), + "YYYY": time.strftime("%Y"), + "YY": time.strftime("%y"), + "MO": time.strftime("%m"), + "DD": time.strftime("%d"), + "HH": time.strftime("%H"), + "MI": time.strftime("%M"), + "SS": time.strftime("%S"), + "JJJ": time.strftime("%j"), + # EXTRA DATA + "SHIFT": "1", + "STATION": "ST-TEN-1", + "OPERATOR": "MARIO", + "BADGE_NUM": "999", + +} + +app = QApplication(sys.argv) + +if "--extra" in sys.argv: + # TEST EXTRA PRINTER + printer = Os_Label_Printer(config=config, name="extra_label_printer") + printer.config_changed() + printer.print_label("MI1.prn") +else: + # TEST STANDARD PRINTER + printer = Os_Label_Printer(config=config, name="label_printer") + printer.config_changed() + printer.print_label("ETA30x16_203dpi.prn", context=context) diff --git a/src/test/label_printerpreform.py b/src/test/label_printerpreform.py new file mode 100644 index 0000000..4d34bd6 --- /dev/null +++ b/src/test/label_printerpreform.py @@ -0,0 +1,55 @@ +import sys +from datetime import datetime +from PyQt5.QtWidgets import QApplication + +from components import Os_Label_Printer +from lib.helpers import ConfigReader + +config = ConfigReader(system_id="st-ten-4") +time =datetime.now() +context = { + # RECIPE DATA + "RECIPE": "000992752", + "PART": "000992752", + "TFILL": "5", + "TSET": "10", + "TTEST": "10", + "PSETMINP_A": "4750", + "PSETMAXP_A": "5250", + "PTEST": "5000", + "PMIN": "30", + "RESPSET": "5123", + "RESLEAK": "12.34", + "SN4": "1234", + # TIME DEFINITION + "DATETIME": time.strftime("%d/%m/%Y %H:%M:%S"), + "DATE": time.strftime("%d/%m/%Y"), + "TIME": time.strftime("%H:%M:%S"), + "YYYY": time.strftime("%Y"), + "YY": time.strftime("%y"), + "MO": time.strftime("%m"), + "DD": time.strftime("%d"), + "HH": time.strftime("%H"), + "MI": time.strftime("%M"), + "SS": time.strftime("%S"), + "JJJ": time.strftime("%j"), + # EXTRA DATA + "SHIFT": "1", + "STATION": "ST-TEN-1", + "OPERATOR": "MARIO", + "BADGE_NUM": "999", + +} + +app = QApplication(sys.argv) + +if "--extra" in sys.argv: + # TEST EXTRA PRINTER + printer = Os_Label_Printer(config=config, name="extra_label_printer") + printer.config_changed() + printer.print_label("MI1.prn") +else: + # TEST STANDARD PRINTER + printer = Os_Label_Printer(config=config, name="label_printer") + printer.config_changed() + printer.print_label("EtichettaR5_Montaggio_1prova.prn", context=context) diff --git a/src/test/rfid.py b/src/test/rfid.py new file mode 100644 index 0000000..ad48bbd --- /dev/null +++ b/src/test/rfid.py @@ -0,0 +1,89 @@ +import logging +import platform +import sys +import time +from datetime import datetime +from pathlib import Path + +import serial +import ndef +import nfc +from nfc.clf import RemoteTarget + + +logging.basicConfig( + format="{asctime}:{name}:{levelname}:{message}", + datefmt="%Y-%m-%dT%H-%M-%S%z", + style="{", + level="INFO", + handlers=[ + logging.StreamHandler(stream=sys.stderr), + logging.FileHandler( + Path("data/logs") / f"{datetime.now().isoformat().replace(':', '_')}.log", + mode="a", + encoding="utf-8", + delay=False, + **({"errors": "surrogateescape"} if sys.version_info.major >= 3 and sys.version_info.minor >= 10 else {}), + ), + ], + force=True, + **({"encoding": "utf-8"} if sys.version_info.major >= 3 and sys.version_info.minor >= 10 else {}), + **({"errors": "surrogateescape"} if sys.version_info.major >= 3 and sys.version_info.minor >= 10 else {}), +) + +connected=False +is_win = platform.system().lower() == "windows" + +if is_win: + dev_list=['COM5:pn532'] +else: + dev_list = ['tty:USB0:pn532', 'tty:USB1:pn532', 'tty:USB2:pn532'] +while True: + try: + if not connected: + clf = nfc.ContactlessFrontend() + for dev in dev_list: + connected = clf.open(dev) + if connected: + print(f"CONNECTED TO {dev}") + break + else: + print(f"UNABLE TO CONNECT TO {dev}") + + 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") + else: + print("NOT CONNECTED") + except Exception as e: + print(f"EXCEPTION {e}") + connected=False + time.sleep(1) + +print("EXITING") +clf.close() \ No newline at end of file diff --git a/src/test_usb586x.py b/src/test_usb586x.py index a6ff41c..0d55c44 100644 --- a/src/test_usb586x.py +++ b/src/test_usb586x.py @@ -3,7 +3,7 @@ import platform import sys import time -if platform.system() == "Windows": +if platform.system().lower() == "windows": sys.path.append(f"{os.getcwd()}\src\components") from src.components.usb_586x import USB_586x from lib.helpers import ConfigReader diff --git a/src/ui/__init__.py b/src/ui/__init__.py index 38627cc..e298bad 100644 --- a/src/ui/__init__.py +++ b/src/ui/__init__.py @@ -1,6 +1,8 @@ +from .dialog import Dialog from .about import About from .archive import Archive from .barcodes_step_editor import Barcodes_Step_Editor +from .barcode_recipe_selection import Barcode_Recipe_Selection from .connector_step_editor import Connector_Step_Editor from .count_step_editor import Count_Step_Editor from .crud import (Cell, Combo_Box_Cell_Widget, CopyPastableCrudQTableWidget, @@ -8,7 +10,6 @@ from .crud import (Cell, Combo_Box_Cell_Widget, CopyPastableCrudQTableWidget, Json_External_Dialog_Cell_Widget, Json_External_Dialog_Editor_Cell_Widget, Line_Edit_Cell_Widget) -from .dialog import Dialog from .editor import Editor from .helpers import calc_foreground_color, replace_widget from .leak_step_editor import Leak_Step_Editor diff --git a/src/ui/barcode_recipe_selection/barcode_recipe_selection.py b/src/ui/barcode_recipe_selection/barcode_recipe_selection.py index 4541d10..7b7249a 100644 --- a/src/ui/barcode_recipe_selection/barcode_recipe_selection.py +++ b/src/ui/barcode_recipe_selection/barcode_recipe_selection.py @@ -7,15 +7,18 @@ 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.test_test import Test_Test from ui.widget import Widget from lib import db from lib.db.models import Recipes test_scan="xxx\nyyy\nzzz" -class Barcode_Recipe_Selection(Widget): +class Barcode_Recipe_Selection(Test_Test): def __init__(self, parent): super().__init__() self.parent=parent + self.components=parent.components self.recipe_db_model=Recipes self.debounce_time = 200 self.barcode_input_l.textChanged.connect(self.debounce) @@ -46,6 +49,7 @@ class Barcode_Recipe_Selection(Widget): self.ok_timer.setSingleShot(True) self.ok_timer.timeout.connect(self.set_recipe) + def start(self, recipe=None, step=None, pieces=None): self.barcode_input_l.setPalette(self.status_palettes[None]) @@ -67,30 +71,33 @@ class Barcode_Recipe_Selection(Widget): if data is None: return else: - lines = data.splitlines() candidates = [i for i in lines if len(i)==10] if len(candidates)>0: # RECIPE CODE FOUND self.recipe=candidates[-1] self.barcode_input_l.setPalette(self.status_palettes[True]) - self.ok_timer.start(2000) + + if "--write-tags" not in sys.argv: + self.ok_timer.start(2000) + else: + self.parent.components["rfid"].write_tag(data) else: # RECIPE CODE NOT FOUND self.barcode_input_l.setPalette(self.status_palettes[False]) self.focus_timer.start(3000) - # LOOKUP RECIPE def set_recipe(self): try: + # LOOKUP RECIPE recipe = self.recipe_db_model.get_by_id(self.recipe) self.parent.set_recipe(recipe) except peewee.DoesNotExist: self.barcode_input_l.setPalette(self.status_palettes[False]) self.focus_timer.start(3000) - self.parent.centralWidget.set_text("RICETTA NON TROVATA",color="red") + self.parent_assembly_widget().set_text("RICETTA NON TROVATA",color="red") def set_focus(self): @@ -98,7 +105,11 @@ class Barcode_Recipe_Selection(Widget): self.barcode_input_l.setPlainText("") self.barcode_input_l.setPalette(self.status_palettes[""]) if getattr(self.parent.centralWidget,"set_text"): - self.parent.centralWidget.set_text("SCANSIONARE BARCODE SELEZIONE RICETTA") + if "fixture_id" in self.components.keys(): + self.parent_assembly_widget().set_text( + "INSERIRE LA DIMA PER SELEZIONARE AUTOMATICAMENTE LA RICETTA DI COLLAUDO") + else: + self.parent_assembly_widget().set_text("SCANSIONARE BARCODE SELEZIONE RICETTA") diff --git a/src/ui/crud/CopyPastableCrudQTableWidget.py b/src/ui/crud/CopyPastableCrudQTableWidget.py index 7709c73..b4b4de9 100644 --- a/src/ui/crud/CopyPastableCrudQTableWidget.py +++ b/src/ui/crud/CopyPastableCrudQTableWidget.py @@ -10,55 +10,56 @@ class CopyPastableCrudQTableWidget(QTableWidget): def eventFilter(self, target, event): if event.type() == QEvent.KeyPress: - if event.key() == Qt.Key_C and (event.modifiers() & Qt.ControlModifier): - if event.key() == Qt.Key_C and (event.modifiers() & Qt.ControlModifier): - copied_cells = sorted(self.selectedIndexes()) - min_row, max_row, min_col, max_col = sys.maxsize, 0, sys.maxsize, 0 - for cell in copied_cells: - row = cell.row() - min_row, max_row = min(row, min_row), max(row, max_row) - col = cell.column() - min_col, max_col = min(col, min_col), max(col, max_col) - if min_row == 0: # if filters row - return False - copy_sparse = {} - for cell in copied_cells: - row = cell.row() - col = cell.column() - if row not in copy_sparse: - copy_sparse[row] = {} - cell = self.cellWidget(row, col) - if cell is not None: - copy_sparse[row][col] = cell.parse(row_number=row, crud=weakref.ref(self.crud)) - copy_dense = [["" for col in range(max_col - min_col + 1)] for row in range(max_row - min_row + 1)] - for row, row_cells in copy_sparse.items(): - for col, cell_text in row_cells.items(): - if cell_text is not None: - copy_dense[row - min_row][col - min_col] = str(cell_text) - copy_text = "\n".join(["\t".join(row) for row in copy_dense]) - QApplication.clipboard().setText(copy_text) - super().keyPressEvent(event) - QApplication.sendEvent(self, event) - return True - elif event.key() == Qt.Key_V and (event.modifiers() & Qt.ControlModifier): - min_row = self.currentRow() - min_col = self.currentColumn() - if min_row == 0: # if filters row - return False - copy_text = QApplication.clipboard().text() - copy_dense = [row.split("\t") for row in copy_text.split("\n")] - if len(copy_dense) > 1 and len(copy_dense[-1]) == 1 and not len(copy_dense[-1][-1]): - copy_dense.pop(-1) - for row, row_cells in enumerate(copy_dense): - for col, cell_text in enumerate(row_cells): - r = min_row + row - c = min_col + col - cell = self.cellWidget(r, c) - if cell is not None: - cell.render(cell_text, field_name=self.crud.select[c] if self.crud is not None else None, row_number=r, crud=weakref.ref(self.crud)) - super().keyPressEvent(event) - QApplication.sendEvent(self, event) - return True + pass + # if event.key() == Qt.Key_C and (event.modifiers() & Qt.ControlModifier): + # if event.key() == Qt.Key_C and (event.modifiers() & Qt.ControlModifier): + # copied_cells = sorted(self.selectedIndexes()) + # min_row, max_row, min_col, max_col = sys.maxsize, 0, sys.maxsize, 0 + # for cell in copied_cells: + # row = cell.row() + # min_row, max_row = min(row, min_row), max(row, max_row) + # col = cell.column() + # min_col, max_col = min(col, min_col), max(col, max_col) + # if min_row == 0: # if filters row + # return False + # copy_sparse = {} + # for cell in copied_cells: + # row = cell.row() + # col = cell.column() + # if row not in copy_sparse: + # copy_sparse[row] = {} + # cell = self.cellWidget(row, col) + # if cell is not None: + # copy_sparse[row][col] = cell.parse(row_number=row, crud=weakref.ref(self.crud)) + # copy_dense = [["" for col in range(max_col - min_col + 1)] for row in range(max_row - min_row + 1)] + # for row, row_cells in copy_sparse.items(): + # for col, cell_text in row_cells.items(): + # if cell_text is not None: + # copy_dense[row - min_row][col - min_col] = str(cell_text) + # copy_text = "\n".join(["\t".join(row) for row in copy_dense]) + # QApplication.clipboard().setText(copy_text) + # super().keyPressEvent(event) + # QApplication.sendEvent(self, event) + # return True + # elif event.key() == Qt.Key_V and (event.modifiers() & Qt.ControlModifier): + # min_row = self.currentRow() + # min_col = self.currentColumn() + # if min_row == 0: # if filters row + # return False + # copy_text = QApplication.clipboard().text() + # copy_dense = [row.split("\t") for row in copy_text.split("\n")] + # if len(copy_dense) > 1 and len(copy_dense[-1]) == 1 and not len(copy_dense[-1][-1]): + # copy_dense.pop(-1) + # for row, row_cells in enumerate(copy_dense): + # for col, cell_text in enumerate(row_cells): + # r = min_row + row + # c = min_col + col + # cell = self.cellWidget(r, c) + # if cell is not None: + # cell.render(cell_text, field_name=self.crud.select[c] if self.crud is not None else None, row_number=r, crud=weakref.ref(self.crud)) + # super().keyPressEvent(event) + # QApplication.sendEvent(self, event) + # return True return super().eventFilter(target, event) def setCellWidget(self, row, column, widget): diff --git a/src/ui/crud/crud.py b/src/ui/crud/crud.py index 79605ac..6eb3e3d 100755 --- a/src/ui/crud/crud.py +++ b/src/ui/crud/crud.py @@ -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) diff --git a/src/ui/leak_step_editor/leak_step_editor.py b/src/ui/leak_step_editor/leak_step_editor.py index 2d5203f..e157ef2 100644 --- a/src/ui/leak_step_editor/leak_step_editor.py +++ b/src/ui/leak_step_editor/leak_step_editor.py @@ -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, diff --git a/src/ui/leak_step_editor/leak_step_editor.ui b/src/ui/leak_step_editor/leak_step_editor.ui index 7b1356b..1bf8742 100644 --- a/src/ui/leak_step_editor/leak_step_editor.ui +++ b/src/ui/leak_step_editor/leak_step_editor.ui @@ -221,7 +221,7 @@ - + 0 @@ -238,7 +238,7 @@ - + 9999 diff --git a/src/ui/main_window/main_window.ui b/src/ui/main_window/main_window.ui index f404bef..0ec3684 100644 --- a/src/ui/main_window/main_window.ui +++ b/src/ui/main_window/main_window.ui @@ -25,7 +25,7 @@ 0 0 843 - 28 + 31 @@ -35,7 +35,7 @@ - About + Informazioni @@ -72,7 +72,7 @@ - Powered by + Contatti diff --git a/src/ui/recipe_selection/recipe_selection.py b/src/ui/recipe_selection/recipe_selection.py index 6410378..06ec26b 100755 --- a/src/ui/recipe_selection/recipe_selection.py +++ b/src/ui/recipe_selection/recipe_selection.py @@ -1,8 +1,6 @@ import csv -import itertools import locale import os -import re import sys import weakref from glob import glob @@ -39,16 +37,13 @@ class Recipe_Selection(Widget): self.unsupported_steps.add("second_leak_test") session = Users.get_session() if session.is_admin: - # readonly = ["id"] readonly = False crud_aliases = { - # "id": "Id", "name": "Ricetta", "client": "Cliente", "part_number": "N° disegno", "spec": "Specifica", "description": "Descrizione", - # "archived": "Archiviata", } filters = None else: @@ -59,7 +54,6 @@ class Recipe_Selection(Widget): "part_number": "N° disegno", "spec": "Specifica", "description": "Descrizione", - # "archived": "Archiviata", } filters = {"archived": False} step_defaults = self.read_steps(self.config.get("recipes_defaults", noner), noner) @@ -134,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()): @@ -220,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"])) @@ -235,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"])) @@ -440,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 "", @@ -453,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"], diff --git a/src/ui/rfid_recipe_selection/__init__.py b/src/ui/rfid_recipe_selection/__init__.py new file mode 100644 index 0000000..b3a3f30 --- /dev/null +++ b/src/ui/rfid_recipe_selection/__init__.py @@ -0,0 +1 @@ +from .rfid_recipe_selection import RFID_Recipe_Selection diff --git a/src/ui/rfid_recipe_selection/rfid_recipe_selection.py b/src/ui/rfid_recipe_selection/rfid_recipe_selection.py new file mode 100644 index 0000000..b4145fc --- /dev/null +++ b/src/ui/rfid_recipe_selection/rfid_recipe_selection.py @@ -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("INSERIRE IL CONNETTORE DI COLLEGAMENTO DIMA PER SELEZIONARE AUTOMATICAMENTE LA RICETTA DI COLLAUDO") + + def instruction_text(self,text,color=None): + if getattr(self.parent.centralWidget, "set_text"): + self.parent.centralWidget.set_text(text, color=color) + + diff --git a/src/ui/rfid_recipe_selection/rfid_recipe_selection.ui b/src/ui/rfid_recipe_selection/rfid_recipe_selection.ui new file mode 100644 index 0000000..2805d48 --- /dev/null +++ b/src/ui/rfid_recipe_selection/rfid_recipe_selection.ui @@ -0,0 +1,95 @@ + + + Test_Connector + + + + 0 + 0 + 1445 + 793 + + + + Test Connector + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 200 + 200 + + + + + 12 + + + + + + + + + + + + 600 + 0 + + + + + 600 + 200 + + + + + 20 + + + + 123 +456 +abc + + + + + + + + 20 + + + + TORNA ALLA TABELLA RICETTE + + + + + + + + diff --git a/src/ui/test/test.py b/src/ui/test/test.py index a222042..9e22d47 100755 --- a/src/ui/test/test.py +++ b/src/ui/test/test.py @@ -3,12 +3,12 @@ import logging import os import sys import weakref -from datetime import datetime +from datetime import datetime, timedelta from lib.db import Archive, Steps, Users from lib.helpers import get_shift from playhouse.shortcuts import model_to_dict -from PyQt5.QtCore import QTimer +from PyQt5.QtCore import QTimer, pyqtSlot from PyQt5.QtWidgets import QMessageBox from ui.helpers import replace_widget from ui.recipe_selection import Recipe_Selection @@ -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,9 +112,10 @@ 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 - if not self.config["autotest_done"]: - self.request_autotest("init") + 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: self.autotest_period = None # INIT TEST DATA @@ -136,6 +136,10 @@ class Test(Widget): # CUSTOM STEP CONNECTIONS self.cycle_available_steps["count"].ok.connect(self.cycle_available_steps["count_end"].widget.set_amount) #self.cycle_available_steps["warning_img"].ok.connect(self.cycle_available_steps["warning_img"].widget.set_done) + + if "fixture_id" in self.components.keys(): + self.components["fixture_id"].new_id_signal.connect(self.load_recipe_from_rfid) + # TESTING if "--test" in sys.argv: self.testing = True @@ -190,14 +194,20 @@ class Test(Widget): replace_widget(self, "centralWidget", widget) def request_autotest(self, reason): # you can cancel the request calling request_autotest(False) - self.log.info(f"cycle request autotest: reason: {reason!r} autotest_request: {self.autotest_request!r}") - if reason == "init": - self.autotest_timer = QTimer() - self.autotest_timer.setSingleShot(False) - self.autotest_timer.timeout.connect(self.request_periodic_autotest) - self.time_timer.start(self.autotest_period) - reason = "boot" - self.autotest_request = reason + if "--no-autotest" not in sys.argv: + + self.log.info(f"cycle request autotest: reason: {reason!r} autotest_request: {self.autotest_request!r}") + if reason in ("init","login"): + self.autotest_timer = QTimer() + self.autotest_timer.setSingleShot(False) + self.autotest_timer.timeout.connect(self.request_periodic_autotest) + if self.autotest_period is not None: + self.autotest_timer.start(self.autotest_period) + reason = "boot" + self.autotest_request = reason + if reason == "logout": + self.next(action="abort") + def request_periodic_autotest(self): self.request_autotest("periodic") @@ -218,13 +228,14 @@ class Test(Widget): # COUNT RESET self.pieces["ok"] = 0 self.pieces["ko"] = 0 - elif action == "fail": + elif action in ("fail","abort"): self.log.info(f"cycle next: action: {action!r}") # FAIL AND RESTART TEST self.step = Steps(type="fail") self.cycle_index = -1 # COUNT FAIL - self.done(ok=False) + if action == "fail": + self.done(ok=False) elif action is not None: raise NotImplementedError(f"cycle next: action {action!r} is not a valid action") # if action did not set the next cycle step @@ -252,6 +263,14 @@ class Test(Widget): else: # autotest ended self.autotesting = False + if self.autotesting_reason == "logout": + Users.logout() + self.main_window.open_login() + else: + t = datetime.now() + self.last_at_l.setText("{d}/{mo}/{y} {h}:{m}".format(y=t.year, mo=t.month, d=t.day, h=t.hour, m=t.minute)) + t+=timedelta(seconds=int(self.autotest_period/1000)) + self.next_at_l.setText("{d}/{mo}/{y} {h}:{m}".format(y=t.year, mo=t.month, d=t.day, h=t.hour, m=t.minute)) self.autotesting_reason = None self.cycle_index = -1 self.config["autotest_done"] = True @@ -314,6 +333,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,15 +370,18 @@ 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") l_at_1={a: float(x) for a, x in l_at_1.items()} - l_at_1["autotest"]=True + l_at_1["autotest"]="ko_check" 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["autotest"]=False + 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)] self.autotest_cycle_steps = [ @@ -392,40 +416,6 @@ class Test(Widget): }), ] if "resistance" not in self.unsupported_steps else []), *(leak_autotest_steps), - # *([ - # Steps(type="leak_1", spec={ - # "pre_filling_time": 0, - # "pre_filling_pressure": 1000, - # "filling_time": 5, - # "settling_time": 5, - # "settling_pressure_min_percent": 5, - # "settling_pressure_max_percent": 5, - # "test_time": 10, - # "test_pressure_min_delta": 5, - # "test_pressure": 9000, - # "test_pressure_max_delta": 5, - # "flush_time": 1, - # "flush_pressure": 100, - # "autotest": True, - # }), - # ] if "leak_1" not in self.unsupported_steps else []), - # *([ - # Steps(type="leak_1", spec={ - # "pre_filling_time": 0, - # "pre_filling_pressure": 1000, - # "filling_time": 5, - # "settling_time": 5, - # "settling_pressure_min_percent": 5, - # "settling_pressure_max_percent": 5, - # "test_time": 10, - # "test_pressure_min_delta": 5, - # "test_pressure": 9000, - # "test_pressure_max_delta": 5, - # "flush_time": 1, - # "flush_pressure": 100, - # "autotest": False, - # }), - # ] if "leak_1" not in self.unsupported_steps else []), Steps(type="done"), Steps(type="wait"), ] @@ -486,13 +476,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( @@ -505,9 +514,13 @@ 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 + self.data["recipe"]["name"] = "AUTOTEST" archived = Archive.archive(self.data, ok and self.data["ok"], overridden=self.data["overridden"]) self.log.info(f"cycle archived locally: {archived!r}") if not self.autotesting: @@ -516,6 +529,11 @@ class Test(Widget): self.pieces["ok"] += 1 else: self.pieces["ko"] += 1 + else: + if self.autotesting_reason == "logout": + if ok: + self.main_window.open_login() + return archived @staticmethod @@ -536,21 +554,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 = { @@ -558,6 +574,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", "-")), @@ -577,24 +594,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}", @@ -611,6 +626,7 @@ class Test(Widget): "HH": archived.time.strftime("%H"), "MI": archived.time.strftime("%M"), "SS": archived.time.strftime("%S"), + "JJJ": archived.time.strftime("%j"), # EXTRA DATA "SHIFT": str(get_shift(archived.time)), "STATION": str(self.config.machine_id), @@ -641,3 +657,16 @@ class Test(Widget): labels = printer_fields["extra_label"].split(",") for label in labels: self.components["extra_label_printer"].print_label(f"{label}.prn", context=None) + + @pyqtSlot(str) + def load_recipe_from_rfid(self,data): + if self.step.type == "barcode_recipe_selection": + if data is not None: + self.cycle_available_steps["barcode_recipe_selection"].widget.get(data) + else: + # fixture removed + pass + else: + if data is not None: + self.fail_cycle() + self.set_recipe_mode_barcode() diff --git a/src/ui/test/test.ui b/src/ui/test/test.ui index 9bdf1aa..7c608ab 100755 --- a/src/ui/test/test.ui +++ b/src/ui/test/test.ui @@ -6,8 +6,8 @@ 0 0 - 842 - 118 + 1252 + 146 @@ -52,26 +52,14 @@ 3 - - + + - + 0 0 - - - 0 - 0 - - - - - 200 - 40 - - 12 @@ -80,11 +68,11 @@ - CAMBIA DISEGNO + N. DISEGNO: - + Qt::Horizontal @@ -97,21 +85,24 @@ - - + + Qt::Horizontal + + QSizePolicy::Fixed + - 40 + 20 20 - - + + 12 @@ -120,27 +111,14 @@ - 12345 + PROSSIMO AUTOTEST: Qt::AlignCenter - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + @@ -157,24 +135,6 @@ - - - - - 12 - 75 - true - - - - 12345 -567 - - - Qt::AlignCenter - - - @@ -201,14 +161,25 @@ - - - - - 0 - 0 - + + + + + 16 + 75 + true + + + - + + + Qt::AlignCenter + + + + + 12 @@ -217,25 +188,15 @@ - N. DISEGNO: + 12345 +567 + + + Qt::AlignCenter - - - - - 12 - 75 - true - - - - OPERATORE: - - - - + @@ -267,7 +228,113 @@ - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 12 + 75 + true + + + + 12345 + + + Qt::AlignCenter + + + + + + + + 12 + 75 + true + + + + OPERATORE: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 200 + 40 + + + + + 12 + 75 + true + + + + CAMBIA DISEGNO + + + + + + + + 12 + 75 + true + + + + ULTIMO AUTOTEST: + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -281,27 +348,28 @@ - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - + + - 16 + 12 + 75 + true + + + + - + + + Qt::AlignCenter + + + + + + + + 12 75 true diff --git a/src/ui/test_assembly/test_assembly.py b/src/ui/test_assembly/test_assembly.py index d10dc5c..fcea393 100755 --- a/src/ui/test_assembly/test_assembly.py +++ b/src/ui/test_assembly/test_assembly.py @@ -22,14 +22,17 @@ class Test_Assembly(Widget): self.img = None self.img_l.setVisible(False) - def set_text(self, text=None,color=None): + def set_text(self, text=None,bg_color=None,text_color=None): if text is not None: self.text = text self.text_l.setText(str(self.text)) self.text_l.setVisible(True) - if color is None: - color = "lime" - self.text_l.setStyleSheet(f"background-color: {color};") + if bg_color is None: + bg_color = "lime" + if text_color is None: + text_color = "black" + + self.text_l.setStyleSheet(f"background-color: {bg_color};color: {text_color}") else: self.text = None diff --git a/src/ui/test_connector/test_connector.py b/src/ui/test_connector/test_connector.py index 69a6eaa..af8f0a5 100644 --- a/src/ui/test_connector/test_connector.py +++ b/src/ui/test_connector/test_connector.py @@ -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() diff --git a/src/ui/test_fail/test_fail.py b/src/ui/test_fail/test_fail.py index f01da20..8d4bb6b 100644 --- a/src/ui/test_fail/test_fail.py +++ b/src/ui/test_fail/test_fail.py @@ -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): - super().__init__(components=components, recipe=recipe, step=step, pieces=pieces, run_once=run_once, reset_on_start=reset_on_start, enable_override=enable_override) + def __init__(self, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=False,parent=None): + super().__init__(components=parent.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() diff --git a/src/ui/test_instructions/test_instructions.py b/src/ui/test_instructions/test_instructions.py index 925620b..0c18da5 100644 --- a/src/ui/test_instructions/test_instructions.py +++ b/src/ui/test_instructions/test_instructions.py @@ -21,6 +21,7 @@ class Test_Instructions(Test_Test): self.svgWidget=None self.svg_root=None self.flag=False + self.inputs={} self.svg_widget=QtSvg.QSvgWidget() self.layout = QVBoxLayout() self.layout.addWidget(self.svg_widget) @@ -31,12 +32,7 @@ class Test_Instructions(Test_Test): def start(self, recipe=None, step=None, pieces=None): show = super().start(recipe=recipe, step=step) - ring_ids=[f"ring_{i+1}" for i in range(step.spec["num_ring"])] - piece_ids=[f"piece_{i+1}" for i in range(step.spec["num_piece"])] - tape_ids=[f"tape_{i+1}" for i in range(step.spec["num_tape"])] - self.ids=ring_ids+piece_ids - self.inputs= {idx: {"id":id,"status":False} for idx,id in enumerate(self.ids)} - self.tapes = {idx: {"id": id, "status": False} for idx, id in enumerate(tape_ids)} + self.timer.start(1000) # setup test loop self.get_connection = self.components["digital_io"].out.connect(self.get) @@ -48,22 +44,26 @@ class Test_Instructions(Test_Test): self.svg_root = etree.parse(svg_path) self.svg_str = etree.tostring(self.svg_root) self.svg_str=etree.tostring(self.svg_root) + + self.monitored_ids=self.svg_root.xpath(f'''.//*[starts-with(@id, 'sensor_')]''') + + self.tape_ids=self.svg_root.xpath(f'''.//*[starts-with(@id, 'tape_')]''') + self.done = False return show def toggle_icons(self): self.flag = not self.flag - for idx,tape in self.tapes.items(): - elem = self.svg_root.findall(f'''.//*[@id='{tape["id"]}']''')[0] + for elem in self.tape_ids: if self.flag: self.show_tape(elem) else: self.hide_tape(elem) - for idx,input in self.inputs.items(): - elem = self.svg_root.findall(f'''.//*[@id='{input["id"]}']''')[0] - if input["status"]: + for elem in self.monitored_ids: + sensor_index = int(elem.attrib['id'].split("_")[1]) - 3 + if self.inputs[sensor_index]: self.show_ok(elem) self.show_icon(elem) else: @@ -76,9 +76,9 @@ class Test_Instructions(Test_Test): self.show_svg() def show_ok(self,id): - id.attrib["{http://www.w3.org/1999/xlink}href"]= f"{self.svg_path}ok.png" + id.attrib["{http://www.w3.org/1999/xlink}href"]= f"{self.svg_path}img/ok.png" def show_ko(self,id): - id.attrib["{http://www.w3.org/1999/xlink}href"]= f"{self.svg_path}arw-yel-down.png" + id.attrib["{http://www.w3.org/1999/xlink}href"]= f"{self.svg_path}img/arw-yel-down.png" def show_icon(self,id): id.set("display", "inline") @@ -87,7 +87,7 @@ class Test_Instructions(Test_Test): id.set("display", "none") def show_tape(self,id): - id.attrib["{http://www.w3.org/1999/xlink}href"]= f"{self.svg_path}tape_black.png" + id.attrib["{http://www.w3.org/1999/xlink}href"]= f"{self.svg_path}img/tape_black.png" id.set("display", "inline") def hide_tape(self,id): @@ -110,13 +110,14 @@ class Test_Instructions(Test_Test): ok = True if len(data[0]["digital_io"])==0: return - for sensor_index,sensor in enumerate(self.ids): + for sensor in self.monitored_ids: + sensor_index = int(sensor.attrib['id'].split("_")[1])-3 byte_idx=int(sensor_index/8) bit_idx=sensor_index%8 if data[0]["digital_io"][byte_idx][bit_idx]: - self.inputs[sensor_index]["status"]=True + self.inputs[sensor_index] = True else: - self.inputs[sensor_index]["status"] = False + self.inputs[sensor_index] = False ok = False if ok: super().get([{ diff --git a/src/ui/test_leak/test_leak.py b/src/ui/test_leak/test_leak.py index d7d3803..b06a9fe 100644 --- a/src/ui/test_leak/test_leak.py +++ b/src/ui/test_leak/test_leak.py @@ -2,24 +2,33 @@ import sys import time import weakref -from PyQt5.QtWidgets import QMessageBox +from PyQt5.QtWidgets import QMessageBox, QDialog, QApplication +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) @@ -87,21 +107,23 @@ class Test_Leak(Test_Test): # TESTING if self.simulate: - if self.step.spec.get("autotest", False) is not True: - data["tecna_t3"] = { - "Running test: result": "-----TESTING----- passed", - } - else: - data["tecna_t3"] = { - "Running test: result": "-----TESTING----- failed", - } + data["tecna_t3"] = { + "Running test: active phase": "WAITING START", + "Running test: result": "-----TESTING----- passed", + "Running test: filling pressure":"5000", + "Running test: measured leak":"5", + "Running test: pressure at the end of settling":"4999", + } if "Running test: result" in data["tecna_t3"]: result = data["tecna_t3"]["Running test: result"] - if self.step.spec.get("autotest", False) is not True: - ok = type(result) is str and "passed" in result.lower() + step=self.step.spec.get("autotest", "") + 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 "passed" in result.lower() # AUTOTEST - LEAK else: - ok = type(result) is str and "failed" in result.lower() + ok = type(result) is str and "passed" in result.lower() # NORMAL TEST if "digital_io" in self.components.keys(): # RESET RELAYS @@ -109,25 +131,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, @@ -143,13 +170,23 @@ class Test_Leak(Test_Test): "END TEST, WAITING THE START OF A NEW TEST" "FINE TEST", }: - if self.step.spec.get("autotest", False) is not True: + if self.step.spec.get("autotest", False) == "ok_check": 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="AUTOTEST: RIMUOVERE FUGA CALIBRATA E PREMERE START PER INIZIARE LA PROVA TENUTA",bg_color="blue",text_color="white") + elif self.step.spec.get("autotest", False) == "ko_check": + if self.parent_assembly_widget is not None : + self.parent_assembly_widget().set_text(text="AUTOTEST: COLLEGARE TUBO-TUBO + FUGA CALIBRATA E PREMERE START PER INIZIARE LA PROVA TENUTA DI PROVA",bg_color="blue",text_color="white") else: if self.parent_assembly_widget is not None: - self.parent_assembly_widget().set_text(text="AUTOTEST: COLLEGARE LA FUGA CALIBRATA E PREMERE START PER INIZIARE LA PROVA TENUTA DI PROVA",color="blue") + self.parent_assembly_widget().set_text(text="COLLEGARE GLI ATTACCHI PNEUMATICI E PREMERE START PER INIZIARE LA PROVA TENUTA") + if self.simulate: + QApplication.processEvents() + time.sleep(2) + 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: diff --git a/src/ui/test_leak/test_leak.ui b/src/ui/test_leak/test_leak.ui index 90ef48e..a9844d9 100644 --- a/src/ui/test_leak/test_leak.ui +++ b/src/ui/test_leak/test_leak.ui @@ -6,8 +6,8 @@ 0 0 - 370 - 491 + 1611 + 894 @@ -26,313 +26,8 @@ 0 - - - - - 12 - 75 - true - - - - PROVA TENUTA - - - - - - - 16 - 50 - false - - - - Tipo di test - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 16 - 50 - false - - - - Pressione del circuito - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 16 - 50 - false - - - - Fase del test - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 16 - 50 - false - - - - Pressione regolatore - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 130 - 16777215 - - - - - 20 - 50 - false - - - - background-color: rgb(255, 255, 255); -border: 1px solid black; - - - - - - - - - - - - - 130 - 16777215 - - - - - 20 - 50 - false - - - - background-color: rgb(255, 255, 255); -border: 1px solid black; - - - - - - - - - - - - - 16 - 50 - false - - - - Perdita - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - - - - - - - - - 130 - 16777215 - - - - - 20 - 50 - false - - - - background-color: rgb(255, 255, 255); -border: 1px solid black; - - - - - - - - - - - - - 16 - 50 - false - - - - Indice di sequenza del test - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 16 - 50 - false - - - - mbar - - - - - - - - 16 - 50 - false - - - - mbar - - - - - - - - 16 - 50 - false - - - - mbar - - - - - - - - 16 - 50 - false - - - - background-color: rgb(255, 255, 255); -border: 1px solid black; - - - - - - - - - - - - - 16 - 50 - false - - - - background-color: rgb(255, 255, 255); -border: 1px solid black; - - - - - - - - - - - - - 16 - 50 - false - - - - background-color: rgb(255, 255, 255); -border: 1px solid black; - - - - - - - - - - - - - + + 0 @@ -345,529 +40,10 @@ border: 1px solid black; 100 - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 255 - 127 - - - - - - - 127 - 255 - 127 - - - - - - - 63 - 255 - 63 - - - - - - - 0 - 127 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 255 - 127 - - - - - - - 85 - 255 - 127 - - - - - - - 0 - 0 - 0 - - - - - - - 127 - 255 - 127 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 255 - 127 - - - - - - - 127 - 255 - 127 - - - - - - - 63 - 255 - 63 - - - - - - - 0 - 127 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 85 - 255 - 127 - - - - - - - 85 - 255 - 127 - - - - - - - 0 - 0 - 0 - - - - - - - 127 - 255 - 127 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - - - 0 - 127 - 0 - - - - - - - 85 - 255 - 127 - - - - - - - 127 - 255 - 127 - - - - - - - 63 - 255 - 63 - - - - - - - 0 - 127 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 127 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 127 - 0 - - - - - - - 85 - 255 - 127 - - - - - - - 85 - 255 - 127 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 255 - 0 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - - - 20 - 75 - true - - - - background-color:rgb(85, 255, 127); - - - START - - - - - - - - 0 - 0 - - - - - 12 - 75 - true - - - - Risultato - - - - - - - 0 - 0 - - - - %v / %m - - - - - - - - 0 - 0 - - - - - 32 - 32 - - - - - - - - - - - - - - - - 0 - 0 - - - + - 0 - 100 + 16777215 + 16777215 @@ -1327,7 +503,1018 @@ border: 1px solid black; - + + + + + 0 + 0 + + + + + 0 + 100 + + + + + + + + + 0 + 0 + 0 + + + + + + + 112 + 112 + 255 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 63 + 63 + + + + + + + 127 + 0 + 0 + + + + + + + 170 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 112 + 112 + 255 + + + + + + + 112 + 112 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 112 + 112 + 255 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 63 + 63 + + + + + + + 127 + 0 + 0 + + + + + + + 170 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 112 + 112 + 255 + + + + + + + 112 + 112 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 127 + 0 + 0 + + + + + + + 112 + 112 + 255 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 63 + 63 + + + + + + + 127 + 0 + 0 + + + + + + + 170 + 0 + 0 + + + + + + + 127 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 0 + 0 + + + + + + + 112 + 112 + 255 + + + + + + + 112 + 112 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 20 + 75 + true + + + + background-color:rgb(112, 112, 255); + + + MOSTRA ISTRUZIONE + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Risultato + + + + + + + 0 + 0 + + + + %v / %m + + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + - + + + + + + + + + + + 0 + 0 + + + + + 0 + 100 + + + + + 16777215 + 16777215 + + + + + + + + + 0 + 0 + 0 + + + + + + + 85 + 255 + 127 + + + + + + + 127 + 255 + 127 + + + + + + + 63 + 255 + 63 + + + + + + + 0 + 127 + 0 + + + + + + + 0 + 170 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 85 + 255 + 127 + + + + + + + 85 + 255 + 127 + + + + + + + 0 + 0 + 0 + + + + + + + 127 + 255 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 85 + 255 + 127 + + + + + + + 127 + 255 + 127 + + + + + + + 63 + 255 + 63 + + + + + + + 0 + 127 + 0 + + + + + + + 0 + 170 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 85 + 255 + 127 + + + + + + + 85 + 255 + 127 + + + + + + + 0 + 0 + 0 + + + + + + + 127 + 255 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 127 + 0 + + + + + + + 85 + 255 + 127 + + + + + + + 127 + 255 + 127 + + + + + + + 63 + 255 + 63 + + + + + + + 0 + 127 + 0 + + + + + + + 0 + 170 + 0 + + + + + + + 0 + 127 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 127 + 0 + + + + + + + 85 + 255 + 127 + + + + + + + 85 + 255 + 127 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 255 + 0 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 20 + 75 + true + + + + background-color:rgb(85, 255, 127); + + + START + + + false + + + false + + + false + + + + @@ -1347,6 +1534,558 @@ border: 1px solid black; + + + + + 12 + 75 + true + + + + PROVA TENUTA + + + + + + + 16 + 50 + false + + + + Caduta massima ammessa + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + Indice di sequenza del test + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16 + 50 + false + + + + Pressione regolatore + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16 + 50 + false + + + + mbar + + + + + + + + 130 + 16777215 + + + + + 20 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + Tipo di test + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 130 + 16777215 + + + + + 20 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + + 48 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + 1/1 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + + 16 + 50 + false + + + + mbar + + + + + + + + 16 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + Pressione del circuito + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 130 + 16777215 + + + + + 20 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + mbar + + + + + + + + 16 + 50 + false + + + + mbar + + + + + + + + 16 + 50 + false + + + + mbar + + + + + + + + 16 + 50 + false + + + + Fase del test + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 130 + 16777215 + + + + + 20 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + Caduta di pressione misurata + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 130 + 16777215 + + + + + 20 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + Pressione di test da ricetta + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16 + 50 + false + + + + Caduta minima ammessa + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 16 + 50 + false + + + + mbar + + + + + + + + 130 + 16777215 + + + + + 20 + 50 + false + + + + background-color: rgb(255, 255, 255); +border: 1px solid black; + + + + - + + + + + + + + 16 + 50 + false + + + + 0 + + + NUMERO TEST + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + - + + + Qt::AlignCenter + + + + + + diff --git a/src/ui/test_test/test_test.py b/src/ui/test_test/test_test.py index 34413bd..225ec40 100644 --- a/src/ui/test_test/test_test.py +++ b/src/ui/test_test/test_test.py @@ -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 @@ -43,13 +45,13 @@ class Test_Test(Widget): self.save_b.clicked.connect(self.save_last) # setup override self.admin_challenged = False - if self.enable_override: - self.override_b.setVisible(True) - self.override_b.setEnabled(True) - elif hasattr(self, "override_b"): - self.override_b.setVisible(False) - self.override_b.setEnabled(False) if hasattr(self, "override_b"): + if self.enable_override: + self.override_b.setVisible(True) + self.override_b.setEnabled(True) + else: + self.override_b.setVisible(False) + self.override_b.setEnabled(False) self.override_b.clicked.connect(self.override) # setup vision staus gui self.parent_assembly_widget = None @@ -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: diff --git a/src/ui/test_vision/test_vision.py b/src/ui/test_vision/test_vision.py index d118eb9..cbb7866 100644 --- a/src/ui/test_vision/test_vision.py +++ b/src/ui/test_vision/test_vision.py @@ -220,7 +220,6 @@ class Test_Vision(Test_Test): frame=self.last.get("frame", None), vision=self.last.get("detections", None), suffix="manual_save", - resize=[256, 256], ) def emit_ok(self):