diff --git a/.gitignore b/.gitignore
index 51b4962..d9a5d35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,4 @@ __pycache__/
/venv*/
runme_custom.sh
runme_custom.bat
+runme_custom_noautotest.bat
\ No newline at end of file
diff --git a/src/test/csv_import/importazione da banco montaggio.csv b/config/csv_import/ST-TEN-6.csv
similarity index 100%
rename from src/test/csv_import/importazione da banco montaggio.csv
rename to config/csv_import/ST-TEN-6.csv
diff --git a/src/test/csv_import/Tabella Tubi riscaldati - COMPLETA rev09_27-10-2022.csv b/config/csv_import/Tabella Tubi riscaldati - COMPLETA rev09_27-10-2022.csv
similarity index 100%
rename from src/test/csv_import/Tabella Tubi riscaldati - COMPLETA rev09_27-10-2022.csv
rename to config/csv_import/Tabella Tubi riscaldati - COMPLETA rev09_27-10-2022.csv
diff --git a/src/test/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.csv b/config/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.csv
similarity index 100%
rename from src/test/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.csv
rename to config/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.csv
diff --git a/src/test/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.xlsx b/config/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.xlsx
similarity index 100%
rename from src/test/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.xlsx
rename to config/csv_import/Tabella Tubi riscaldati - COMPLETA rev19_29-12-2022.xlsx
diff --git a/src/test/csv_import/Tabella Tubi riscaldati - campi extra.csv b/config/csv_import/Tabella Tubi riscaldati - campi extra.csv
similarity index 100%
rename from src/test/csv_import/Tabella Tubi riscaldati - campi extra.csv
rename to config/csv_import/Tabella Tubi riscaldati - campi extra.csv
diff --git a/config/csv_import/Tabella_e_daily.csv b/config/csv_import/Tabella_e_daily.csv
new file mode 100644
index 0000000..57fc62a
--- /dev/null
+++ b/config/csv_import/Tabella_e_daily.csv
@@ -0,0 +1,238 @@
+codice_ricetta,Priorita,Descrizione,etichette_supplementari,pressione_di_test_delta_massimo,pressione_di_test_delta_minimo
+5803034806,1,,,30,30
+5803037204,1,,,30,30
+5803037206,1,,,30,30
+5803037207,1,,,30,30
+5803048121,1,,,30,30
+5803048122,1,,,30,30
+5803048123,1,,,30,30
+5803048125,1,,RM2,30,30
+5803048126,1,,MI2,30,30
+5803048127,1,,"MI1,MI2",30,30
+5803048128,1,,"RM1,RM2",30,30
+5803048131,1,,"MI1,MI2",30,30
+5803048132,1,,"RM1,RM2",30,30
+5803098374,1,,,30,30
+5803098375,1,,,30,30
+5803119920,1,,,30,30
+5803119921,1,,,30,30
+5803119922,1,,,30,30
+5803119923,1,,,30,30
+5803119924,1,,,30,30
+5803119925,1,,,30,30
+5803119926,1,,,30,30
+5803119927,1,,,30,30
+5802850925,1,,"RM1,MI1",30,30
+5802850926,1,,,20,20
+5802850929,1,,,30,30
+5802850932,1,,,30,30
+5802850933,1,,,30,30
+5802850941,1,,,30,30
+5802963590,1,,,30,30
+5802963591,1,,RB1,30,30
+5802963593,1,,,30,30
+5802963597,1,,,30,30
+5802963598,1,,MB1,20,20
+5802963599,1,,,30,30
+5802963600,1,,,30,30
+5802963679,1,,,30,30
+5802963681,1,,,20,20
+5802963683,1,,,30,30
+5802963684,1,,,30,30
+5802963685,1,,,30,30
+5803025107,1,,"MI1,MI2",30,30
+5803025111,1,,"MB1,MB2",30,30
+5803025112,1,,"RB1,RB2",30,30
+5803025113,1,,"MI1,MI2",30,30
+5803025114,1,,"RM1,RM2",30,30
+5803025116,1,,"MI1,MI2",30,30
+5803025117,1,,"RM1,RM2",30,30
+5803025127,1,,"MI1,MI2",30,30
+5803025130,1,,,30,30
+5803025131,1,,,30,30
+5803025134,1,,,30,30
+5803025135,1,,,30,30
+5803025136,1,,,30,30
+5803025137,1,,,30,30
+5803033719,1,,"MI1,MI2",30,30
+5803034025,1,,"RM1,RM2",30,30
+5803034029,1,,,30,30
+5803034807,1,,"RM1,RM2",30,30
+5803036737,1,,,30,30
+5803041432,1,,,30,30
+5803041433,1,,,30,30
+5802850935,1,,,30,30
+5802850936,1,,,30,30
+5803025108,1,,"RM1,RM2",30,30
+5803025109,1,,MI2,30,30
+5803025110,1,,RM2,30,30
+5803025115,1,,MB2,30,30
+5803025118,1,,RB2,30,30
+5803025132,1,,,30,30
+5803025133,1,,,30,30
+5803033717,1,,MI1,30,30
+5803034002,1,,,30,30
+5803034005,1,,,30,30
+5803034011,1,,,30,30
+5803034015,1,,RM1,30,30
+5803034017,1,,MB2,30,30
+5803034020,1,,,30,30
+5803034021,1,,,30,30
+5803034022,1,,,30,30
+5803034026,1,,"RB1,RB2",30,30
+5803034027,1,,MB2,30,30
+5803034028,1,,RB2,30,30
+5803034770,1,,,30,30
+5803034771,1,,,30,30
+5803034772,1,,"MB1,MB2",30,30
+5803036730,1,,RB2,30,30
+5803036731,1,,"RM1,RM2",30,30
+5803036732,1,,MI2,30,30
+5803036733,1,,RM2,30,30
+5803036734,1,,MB2,30,30
+5803036735,1,,RB2,30,30
+5803036741,1,,MI1,30,30
+5803036742,1,,RM1,30,30
+5803036743,1,,MI1,30,30
+5803036744,1,,RM1,30,30
+5803036746,1,,RB1,30,30
+5803036747,1,,MB1,30,30
+5803036751,1,,,30,30
+5803036753,1,,,30,30
+5803041434,1,,MB1,30,30
+5803041435,1,,RB1,30,30
+5803048129,1,,MI2,30,30
+5803048130,1,,RM2,30,30
+5803041436,2,,RM2,30,30
+5803041437,2,,MI2,30,30
+5803036748,2,,MI2,30,30
+5803036749,2,,RM2,30,30
+5803034810,2,,MI1,30,30
+5803034811,2,,RM1,30,30
+5803101533,2,,"RM1,RM2",30,30
+5803101535,2,,"MI1,MI2",30,30
+5803101537,2,,RM1,30,30
+5803101538,2,,MI1,30,30
+5803108304,2,,,30,30
+5803108310,2,,,30,30
+5803101534,2,,RM2,30,30
+5803101536,2,,MI2,30,30
+5803033718,2,,,30,30
+5803034812,2,,,30,30
+5803034813,2,,,30,30
+5803108305,2,,,30,30
+5803108311,2,,,30,30
+5803007806,2,,,30,30
+5803007807,2,,,30,30
+5803007808,2,,,30,30
+5803034023,2,,RM1,30,30
+5803034024,2,,MI1,30,30
+5803101541,2,,RM1,30,30
+5803101542,2,,MI1,30,30
+5803034778,2,,MB2,30,30
+5803034780,2,,RB2,30,30
+5803037200,2,,RM1,30,30
+5803037201,2,,MI1,30,30
+5803104802,2,,,30,30
+5803104803,2,,,30,30
+5803104804,2,,,30,30
+5803104806,2,,,30,30
+5803104807,2,,,30,30
+5803104808,2,,,30,30
+5803025103,2,,MB2,30,30
+5803025105,2,,RB2,30,30
+5802815391,2,,,30,30
+5802815400,2,,,30,30
+5803047088,2,,MB2,30,30
+5803047079,2,,MB2,30,30
+5803047080,2,,RB2,30,30
+5803047095,2,,MB2,30,30
+5803047096,2,,RB2,30,30
+5803034808,2,,"MI1,MI2",30,30
+5803034809,2,,"RM1,RM2",30,30
+5803108365,2,,,30,30
+5803108368,2,,,30,30
+5803034007,2,,,30,30
+5803034009,2,,,30,30
+5803037202,2,,,30,30
+5803037203,2,,,30,30
+5803108366,2,,,30,30
+5803108369,2,,,30,30
+5803025123,2,,"MI1,MI2",30,30
+5803025124,2,,"RM1,RM2",30,30
+5803025125,2,,MI1,30,30
+5803025126,2,,RM1,30,30
+5803034773,2,,RM1,30,30
+5803033716,2,,RM1,30,30
+5803034013,2,,MI1,30,30
+5803025100,2,,"MI1,MI2",30,30
+5803025101,2,,"RB1,RB2",30,30
+5803047093,2,,"MB1,MB2",30,30
+5803025099,2,,"MB1,MB2",30,30
+5803025102,2,,"RM1,RM2",30,30
+5803025104,2,,"MI1,MI2",30,30
+5803025106,2,,"RM1,RM2",30,30
+5803047087,2,,"MI1,MI2",30,30
+5803047090,2,,"RM1,RM2",30,30
+5803047092,2,,"MI1,MI2",30,30
+5803025128,2,,,30,30
+5803025129,2,,,30,30
+5803047075,2,,RM2,30,30
+5803047076,2,,MI2,30,30
+5803034776,2,,,30,30
+5803047073,2,,RM1,30,30
+5803047074,2,,MI1,30,30
+5803034774,2,,MI1,30,30
+5803036739,2,,MI1,30,30
+5803036740,2,,RM1,30,30
+5803047098,2,,,30,30
+5803047099,2,,,30,30
+5802815398,2,,,30,30
+5803047091,2,,RB2,30,30
+5803223729,3,priorita 3,MI2,30,30
+5803223730,3,priorita 3,"MI1,MI2",30,30
+5803223731,3,priorita 3,MB2,30,30
+5803223732,3,priorita 3,"RM1,RM2",30,30
+5803223733,3,priorita 3,RM2,30,30
+5803223734,3,priorita 3,RB2,30,30
+5803223735,3,priorita 3,,30,30
+5803223736,3,priorita 3,,30,30
+5803223737,3,priorita 3,,30,30
+5803223738,3,priorita 3,,30,30
+5803223739,3,priorita 3,,30,30
+5803223740,3,priorita 3,,30,30
+5803223741,3,priorita 3,,30,30
+5803223742,3,priorita 3,,30,30
+5803223743,3,priorita 3,,30,30
+5803223744,3,priorita 3,,30,30
+5803223745,3,priorita 3,,30,30
+5803223746,3,priorita 3,RM2,30,30
+5803223747,3,priorita 3,MI2,30,30
+5803223748,3,priorita 3,"RM1,RM2",30,30
+5803223749,3,priorita 3,"MI1,MI2",30,30
+5803223750,3,priorita 3,RB2,30,30
+5803223751,3,priorita 3,MB2,30,30
+5803223752,3,priorita 3,RM2,30,30
+5803223753,3,priorita 3,MI2,30,30
+5803120372,3,priorita 3,RB2,30,30
+5803120373,3,priorita 3,MB2,30,30
+5803120374,3,priorita 3,,30,30
+5803120375,3,priorita 3,,30,30
+5803101543,3,priorita 3,MI1,30,30
+5803101544,3,priorita 3,RM1,30,30
+5803101545,3,priorita 3,"RM1,RM2",30,30
+5803101546,3,priorita 3,"MI1,MI2",30,30
+5803101547,3,priorita 3,,30,30
+5803223754,3,priorita 3,,30,30
+5803223755,3,priorita 3,,30,30
+5803120371,3,priorita 3,,30,30
+5803228584,3,priorita 3,,30,30
+5803228585,3,priorita 3,,30,30
+5803236684,4,priorita 4,,30,30
+5803236685,4,priorita 4,,30,30
+5803229237,5,priorita 5,RB1,30,30
+5803229239,5,priorita 5,MB1,30,30
+5803229240,5,priorita 5,RM2,30,30
+5803229242,5,priorita 5,MI2,30,30
+5803229244,5,priorita 5,"RB1,RB2",30,30
+5803229245,5,priorita 5,"MB1,MB2",30,30
diff --git a/src/test/csv_import/importazione da banco montaggio.ods b/config/csv_import/importazione da banco montaggio.ods
similarity index 100%
rename from src/test/csv_import/importazione da banco montaggio.ods
rename to config/csv_import/importazione da banco montaggio.ods
diff --git a/config/csv_import/importazione da banco preformatura.csv b/config/csv_import/importazione da banco preformatura.csv
new file mode 100644
index 0000000..9449504
--- /dev/null
+++ b/config/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/config/csv_import/st-ten-8.csv b/config/csv_import/st-ten-8.csv
new file mode 100644
index 0000000..67f4837
--- /dev/null
+++ b/config/csv_import/st-ten-8.csv
@@ -0,0 +1,8 @@
+codice_ricetta,cliente,codice_prodotto,descrizione,tempo_riempimento,tempo_assestamento,tempo_di_test,percentuale_minima_pressione_assestamento,percentuale_massima_pressione_assestamento,pressione_di_test_delta_minimo,pressione_di_test,pressione_di_test_delta_massimo,modello_etichetta,richiedi_inserimento_scarto,istruzione_abilitata,tempo_svuotamento
+5803112815,IVECO,5803112815,Daily Automatico,5,10,10,5,5,30,5000,5,ETA30x16_203dpi.prn,x,x,1
+5803112816,IVECO,5803112816,Daily Automatico,5,10,10,5,5,30,5000,5,ETA30x16_203dpi.prn,x,x,1
+000746453 REV.5,FERRARI,000746453 REV.5,TUBO RITORNO OLIO,10,30,20,5,5,25,10000,5,ferrari_stten8.prn,,,1
+MY83-6L701-AB,ASTON MARTIN,MY83-6L701-AB,TRANSMISSION OIL,5,10,10,5,5,30,7000,5,aston_martin.prn,,,1
+MY83-6L694-AB,ASTON MARTIN,MY83-6L694-AB,TRANSMISSION OIL,5,10,10,5,5,30,7000,5,aston_martin.prn,,,1
+MY83-6B747-BA,ASTON MARTIN,MY83-6B747-BA,ENGINE OIL,5,10,10,5,5,30,7000,5,aston_martin.prn,,,1
+MY83-6B748-BA,ASTON MARTIN,MY83-6B748-BA,ENGINE OIL,5,10,10,5,5,30,7000,5,aston_martin.prn,,,1
\ No newline at end of file
diff --git a/config/csv_import/st-ten-9.csv b/config/csv_import/st-ten-9.csv
new file mode 100644
index 0000000..b29b8b6
--- /dev/null
+++ b/config/csv_import/st-ten-9.csv
@@ -0,0 +1,2 @@
+codice_ricetta,cliente,codice_prodotto,descrizione
+R54967,Errecinque,R54967, Tubo in metallo
\ No newline at end of file
diff --git a/src/test/csv_import/test.py b/config/csv_import/test.py
similarity index 100%
rename from src/test/csv_import/test.py
rename to config/csv_import/test.py
diff --git a/src/test/csv_import/test_doppia_prova_tenuta.csv b/config/csv_import/test_doppia_prova_tenuta.csv
similarity index 68%
rename from src/test/csv_import/test_doppia_prova_tenuta.csv
rename to config/csv_import/test_doppia_prova_tenuta.csv
index 7a7fa73..55ab042 100644
--- a/src/test/csv_import/test_doppia_prova_tenuta.csv
+++ b/config/csv_import/test_doppia_prova_tenuta.csv
@@ -1,3 +1,3 @@
-codice_ricetta,codice_prodotto,cliente,descrizione,prova_tenuta_abilitata,prova_tenuta_abilitata_2,config_elettrovalvole,config_elettrovalvole_2,modello_etichetta
+codice_ricetta,codice_prodotto,cliente,descrizione,prova_tenuta_abilitata,prova_tenuta_abilitata_2,canale_di_prova,canale_di_prova_2,modello_etichetta
5802820548,5802820548,IVECO,Tubo doppio,x,x,0,1,EtichettaR5_Montaggio_2prove.prn
5802820549,5802820549,IVECO,Tubo singolo,x,,0,1,EtichettaR5_Montaggio.prn
diff --git a/config/csv_import/test_import_himatic my24.csv b/config/csv_import/test_import_himatic my24.csv
new file mode 100644
index 0000000..acf0c77
--- /dev/null
+++ b/config/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/csv_import/test_import_himatic.csv b/config/csv_import/test_import_himatic.csv
similarity index 100%
rename from src/test/csv_import/test_import_himatic.csv
rename to config/csv_import/test_import_himatic.csv
diff --git a/src/test/csv_import/test_import_himatic.xlsx b/config/csv_import/test_import_himatic.xlsx
similarity index 100%
rename from src/test/csv_import/test_import_himatic.xlsx
rename to config/csv_import/test_import_himatic.xlsx
diff --git a/src/test/csv_import/test_import_leak_only.csv b/config/csv_import/test_import_leak_only.csv
similarity index 100%
rename from src/test/csv_import/test_import_leak_only.csv
rename to config/csv_import/test_import_leak_only.csv
diff --git a/src/test/csv_import/test_tecna_upload.csv b/config/csv_import/test_tecna_upload.csv
similarity index 100%
rename from src/test/csv_import/test_tecna_upload.csv
rename to config/csv_import/test_tecna_upload.csv
diff --git a/src/test/csv_import/tst.csv b/config/csv_import/tst.csv
similarity index 100%
rename from src/test/csv_import/tst.csv
rename to config/csv_import/tst.csv
diff --git a/config/instruction_images/st-ten-8/5803112815.svg b/config/instruction_images/st-ten-8/5803112815.svg
new file mode 100644
index 0000000..8e90441
--- /dev/null
+++ b/config/instruction_images/st-ten-8/5803112815.svg
@@ -0,0 +1,80 @@
+
+
+
+
diff --git a/config/instruction_images/st-ten-8/5803112816.svg b/config/instruction_images/st-ten-8/5803112816.svg
new file mode 100644
index 0000000..f4b0c60
--- /dev/null
+++ b/config/instruction_images/st-ten-8/5803112816.svg
@@ -0,0 +1,80 @@
+
+
+
+
diff --git a/config/instruction_images/st-ten-8/DEFAULT.svg b/config/instruction_images/st-ten-8/DEFAULT.svg
new file mode 100644
index 0000000..facc0bb
--- /dev/null
+++ b/config/instruction_images/st-ten-8/DEFAULT.svg
@@ -0,0 +1,49 @@
+
+
+
+
diff --git a/config/instruction_images/st-ten-8/img/arw-yel-down.png b/config/instruction_images/st-ten-8/img/arw-yel-down.png
new file mode 100644
index 0000000..bb3c668
Binary files /dev/null and b/config/instruction_images/st-ten-8/img/arw-yel-down.png differ
diff --git a/config/instruction_images/st-ten-8/img/ok.png b/config/instruction_images/st-ten-8/img/ok.png
new file mode 100644
index 0000000..d576b7d
Binary files /dev/null and b/config/instruction_images/st-ten-8/img/ok.png differ
diff --git a/config/instruction_images/st-ten-8/img/tape_black.png b/config/instruction_images/st-ten-8/img/tape_black.png
new file mode 100644
index 0000000..0d51c4b
Binary files /dev/null and b/config/instruction_images/st-ten-8/img/tape_black.png differ
diff --git a/config/instruction_images/st-ten-8/img/tape_white.png b/config/instruction_images/st-ten-8/img/tape_white.png
new file mode 100644
index 0000000..d4b64f0
Binary files /dev/null and b/config/instruction_images/st-ten-8/img/tape_white.png differ
diff --git a/config/label_designs/ASTON MARTIN/aston_martin.nlbl b/config/label_designs/ASTON MARTIN/aston_martin.nlbl
new file mode 100644
index 0000000..dbc2619
Binary files /dev/null and b/config/label_designs/ASTON MARTIN/aston_martin.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/MB1.nlbl b/config/label_designs/E-DAILY - ZT231/MB1.nlbl
new file mode 100644
index 0000000..9097ad9
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/MB1.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/MB2.nlbl b/config/label_designs/E-DAILY - ZT231/MB2.nlbl
new file mode 100644
index 0000000..7e538d6
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/MB2.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/MI1.nlbl b/config/label_designs/E-DAILY - ZT231/MI1.nlbl
new file mode 100644
index 0000000..95d2648
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/MI1.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/MI2.nlbl b/config/label_designs/E-DAILY - ZT231/MI2.nlbl
new file mode 100644
index 0000000..721aa6c
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/MI2.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/RB1.nlbl b/config/label_designs/E-DAILY - ZT231/RB1.nlbl
new file mode 100644
index 0000000..584660c
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/RB1.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/RB2.nlbl b/config/label_designs/E-DAILY - ZT231/RB2.nlbl
new file mode 100644
index 0000000..fbb7525
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/RB2.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/RM1.nlbl b/config/label_designs/E-DAILY - ZT231/RM1.nlbl
new file mode 100644
index 0000000..75de31b
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/RM1.nlbl differ
diff --git a/config/label_designs/E-DAILY - ZT231/RM2.nlbl b/config/label_designs/E-DAILY - ZT231/RM2.nlbl
new file mode 100644
index 0000000..61cdd52
Binary files /dev/null and b/config/label_designs/E-DAILY - ZT231/RM2.nlbl differ
diff --git a/config/label_designs/FERRARI/000746453.nlbl b/config/label_designs/FERRARI/000746453.nlbl
new file mode 100644
index 0000000..7147ec4
Binary files /dev/null and b/config/label_designs/FERRARI/000746453.nlbl differ
diff --git a/config/label_designs/FERRARI/000952054.nlbl b/config/label_designs/FERRARI/000952054.nlbl
new file mode 100644
index 0000000..b693b60
Binary files /dev/null and b/config/label_designs/FERRARI/000952054.nlbl differ
diff --git a/config/label_designs/FERRARI/F164F169.nlbl b/config/label_designs/FERRARI/F164F169.nlbl
new file mode 100644
index 0000000..1f7dd29
Binary files /dev/null and b/config/label_designs/FERRARI/F164F169.nlbl differ
diff --git a/config/label_designs/SATIL/R5_30x17_203dpi.nlbl b/config/label_designs/SATIL/R5_30x17_203dpi.nlbl
new file mode 100644
index 0000000..50a477a
Binary files /dev/null and b/config/label_designs/SATIL/R5_30x17_203dpi.nlbl differ
diff --git a/config/label_templates/F164F169.prn b/config/label_templates/F164F169.prn
new file mode 100644
index 0000000..e60552d
--- /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
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW472
+^LL1654
+^LS0
+^FT40,729^A0N,38,33^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
+^FT259,729^A0N,38,33^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
+^FT27,1497^A0N,46,46^FH\^CI28^FDESITO:^FS^CI27
+^FT213,1497^A0N,46,46^FH\^CI28^FDCONFORME^FS^CI27
+^FT43,107^A0N,38,38^FH\^CI28^FDNumero Disegno^FS^CI27
+^FT40,683^A0N,38,38^FH\^CI28^FDData/Ora Prova^FS^CI27
+^FT40,784^A0N,38,38^FH\^CI28^FDStazione: {STATION}^FS^CI27
+^FT40,615^A0N,38,38^FH\^CI28^FDN. Pezzo:^FS^CI27
+^FT200,617^A0N,38,38^FH\^CI28^FD{SN4}^FS^CI27
+^FT40,831^A0N,38,38^FH\^CI28^FDOPERATORE: {BADGE_NUM}^FS^CI27
+^FO77,960^GB318,0,12^FS
+^FT28,1043^A0N,38,38^FH\^CI28^FDP. prova:^FS^CI27
+^FT28,1090^A0N,38,38^FH\^CI28^FDP. rilevata:^FS^CI27
+^FT214,1090^A0N,38,38^FH\^CI28^FD{RESPSET}mbar^FS^CI27
+^FT28,1130^A0N,38,38^FH\^CI28^FDCaduta ammessa:^FS^CI27
+^FT305,1130^A0N,38,38^FH\^CI28^FD{PMIN} mbar^FS^CI27
+^FT28,1179^A0N,38,38^FH\^CI28^FDCaduta rilevata:^FS^CI27
+^FT264,1179^A0N,38,38^FH\^CI28^FD{RESLEAK} mbar^FS^CI27
+^FT28,1342^A0N,38,38^FH\^CI28^FDT.Prova^FS^CI27
+^FT306,1348^A0N,38,38^FH\^CI28^FD{TTEST} s^FS^CI27
+^FT27,1278^A0N,38,38^FH\^CI28^FDT.Riempim.^FS^CI27
+^FT306,1278^A0N,38,38^FH\^CI28^FD{TFILL} s^FS^CI27
+^FT28,1310^A0N,38,38^FH\^CI28^FDT.Stabilizzazione^FS^CI27
+^FT306,1313^A0N,38,38^FH\^CI28^FD{TSET} s^FS^CI27
+^FT214,1043^A0N,38,38^FH\^CI28^FD{PTEST} mbar^FS^CI27
+^FT46,370^BXN,9,200,0,0,1,_,1
+^FH\^FD{PART}{HH}{MI}{JJJ}{YY}^FS
+^FT43,161^A0N,38,38^FH\^CI28^FD992752^FS^CI27
+^FT43,425^A0N,38,38^FH\^CI28^FD{PART}{HH}{MI}{JJJ}{YY}^FS^CI27
+^FT40,879^A0N,38,38^FH\^CI28^FDGB16897 / {DD}/{MO}/{YY}^FS^CI27
+^FT40,925^A0N,38,38^FH\^CI28^FDERRECINQUE / 21882^FS^CI27
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/aston_martin.prn b/config/label_templates/aston_martin.prn
new file mode 100644
index 0000000..cdf9194
--- /dev/null
+++ b/config/label_templates/aston_martin.prn
@@ -0,0 +1,59 @@
+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
+^PW336
+^LL1055
+^LS0
+^FT65,66^A0N,39,38^FH\^CI28^FDERRECINQUE^FS^CI27
+^BY1,3,56^FT52,291^BCN,,N,N
+^FH\^FD>:{PART}^FS
+^FT23,382^A0N,31,30^FH\^CI28^FDPart number:^FS^CI27
+^FT23,455^A0N,31,30^FH\^CI28^FD{PART}^FS^CI27
+^FT25,101^A0N,17,18^FH\^CI28^FDVia Meucci 31/A - 10079 Mappano(TO)^FS^CI27
+^FT61,173^A0N,39,38^FH\^CI28^FD{CLIENT}^FS^CI27
+^FT61,211^A0N,39,38^FH\^CI28^FDLEAK TEST^FS^CI27
+^FT23,921^A0N,23,23^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
+^FT169,921^A0N,23,23^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
+^FT25,1006^A0N,31,30^FH\^CI28^FDCHECK:^FS^CI27
+^FT151,1006^A0N,31,30^FH\^CI28^FDPASSED^FS^CI27
+^FT23,964^A0N,25,25^FH\^CI28^FDOperator:^FS^CI27
+^FT151,964^A0N,25,25^FH\^CI28^FD{OPERATOR}^FS^CI27
+^FT51,323^A0N,31,30^FH\^CI28^FD{PART}^FS^CI27
+^FT23,417^A0N,31,30^FH\^CI28^FD{DESCRIPTION}^FS^CI27
+^FT23,513^A0N,31,30^FH\^CI28^FDSequential number:^FS^CI27
+^FT23,548^A0N,31,30^FH\^CI28^FD{SN5}^FS^CI27
+^FT27,658^A0N,28,28^FH\^CI28^FDTest 1:^FS^CI27
+^FT27,685^A0N,23,23^FH\^CI28^FDMeasured press.:^FS^CI27
+^FT199,687^A0N,20,20^FH\^CI28^FD{RESPSET} mbar^FS^CI27
+^FT27,707^A0N,23,23^FH\^CI28^FDAllowed leak:^FS^CI27
+^FT199,709^A0N,20,20^FH\^CI28^FD{PMIN} mbar^FS^CI27
+^FT27,730^A0N,23,23^FH\^CI28^FDMeasured leak:^FS^CI27
+^FT187,731^A0N,20,20^FH\^CI28^FD{RESLEAK} mbar^FS^CI27
+^FT27,817^A0N,23,23^FH\^CI28^FDMeasure time:^FS^CI27
+^FT215,818^A0N,20,20^FH\^CI28^FD{TTEST} s^FS^CI27
+^FT26,773^A0N,23,23^FH\^CI28^FDFill time:^FS^CI27
+^FT215,770^A0N,20,20^FH\^CI28^FD{TFILL} s^FS^CI27
+^FT27,795^A0N,23,23^FH\^CI28^FDSettling time:^FS^CI27
+^FT215,794^A0N,20,20^FH\^CI28^FD{TSET} s^FS^CI27
+^FT136,658^A0N,28,28^FH\^CI28^FD{PTEST} mbar^FS^CI27
+^FT151,124^A0N,17,18^FH\^CI28^FDItaly^FS^CI27
+^FT27,893^A0N,23,23^FH\^CI28^FDTest date/time:^FS^CI27
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/ferrari_c01.prn b/config/label_templates/ferrari_c01.prn
new file mode 100644
index 0000000..15efb50
--- /dev/null
+++ b/config/label_templates/ferrari_c01.prn
@@ -0,0 +1,53 @@
+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
+^PW472
+^LL1654
+^LS0
+^FT40,729^A0N,38,33^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
+^FT259,729^A0N,38,33^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
+^FT27,1497^A0N,46,46^FH\^CI28^FDESITO:^FS^CI27
+^FT213,1497^A0N,46,46^FH\^CI28^FDCONFORME^FS^CI27
+^FT43,130^A0N,38,38^FH\^CI28^FDNumero Disegno^FS^CI27
+^FT40,683^A0N,38,38^FH\^CI28^FDData/Ora Prova^FS^CI27
+^FT40,784^A0N,38,38^FH\^CI28^FDStazione: {STATION}^FS^CI27
+^FT40,615^A0N,38,38^FH\^CI28^FDN. Pezzo:^FS^CI27
+^FT200,617^A0N,38,38^FH\^CI28^FD{SN5}^FS^CI27
+^FT40,831^A0N,38,38^FH\^CI28^FDOPERATORE: {OPERATOR}^FS^CI27
+^FO77,960^GB318,0,12^FS
+^FT28,1043^A0N,38,38^FH\^CI28^FDP. prova:^FS^CI27
+^FT28,1090^A0N,38,38^FH\^CI28^FDP. rilevata:^FS^CI27
+^FT214,1090^A0N,38,38^FH\^CI28^FD{RESPSET}mbar^FS^CI27
+^FT28,1130^A0N,38,38^FH\^CI28^FDCaduta ammessa:^FS^CI27
+^FT305,1130^A0N,38,38^FH\^CI28^FD{PMIN} mbar^FS^CI27
+^FT28,1179^A0N,38,38^FH\^CI28^FDCaduta rilevata:^FS^CI27
+^FT264,1179^A0N,38,38^FH\^CI28^FD{RESLEAK} mbar^FS^CI27
+^FT28,1342^A0N,38,38^FH\^CI28^FDT.Prova^FS^CI27
+^FT306,1348^A0N,38,38^FH\^CI28^FD{TTEST} s^FS^CI27
+^FT27,1278^A0N,38,38^FH\^CI28^FDT.Riempim.^FS^CI27
+^FT306,1278^A0N,38,38^FH\^CI28^FD{TFILL} s^FS^CI27
+^FT28,1310^A0N,38,38^FH\^CI28^FDT.Stabilizzazione^FS^CI27
+^FT306,1313^A0N,38,38^FH\^CI28^FD{TSET} s^FS^CI27
+^FT214,1043^A0N,38,38^FH\^CI28^FD{PTEST} mbar^FS^CI27
+^FT46,352^BXN,9,200,0,0,1,_,1
+^FH\^FD{PART}{MO}{YY}{SN5}^FS
+^FT43,425^A0N,38,38^FH\^CI28^FD{PART}{MO}{YY}{SN5}^FS^CI27
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/ferrari_stten8.prn b/config/label_templates/ferrari_stten8.prn
new file mode 100644
index 0000000..ab9abe9
--- /dev/null
+++ b/config/label_templates/ferrari_stten8.prn
@@ -0,0 +1,58 @@
+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
+^PW336
+^LL1055
+^LS0
+^FT65,66^A0N,39,38^FH\^CI28^FDERRECINQUE^FS^CI27
+^FT52,403^BQN,2,7
+^FH\^FDLA,{PART}^FS
+^FT23,436^A0N,31,30^FH\^CI28^FDPart number:^FS^CI27
+^FT23,527^A0N,31,30^FH\^CI28^FD{PART}^FS^CI27
+^FT25,101^A0N,17,18^FH\^CI28^FDVia Meucci 31/A - 10079 Mappano(TO)^FS^CI27
+^FT61,173^A0N,39,38^FH\^CI28^FD{CLIENT}^FS^CI27
+^FT61,211^A0N,39,38^FH\^CI28^FDLEAK TEST^FS^CI27
+^FT23,921^A0N,23,23^FH\^CI28^FD{DD}/{MO}/{YY}^FS^CI27
+^FT169,921^A0N,23,23^FH\^CI28^FD{HH}:{MI}:{SS}^FS^CI27
+^FT25,1006^A0N,31,30^FH\^CI28^FDCHECK:^FS^CI27
+^FT151,1006^A0N,31,30^FH\^CI28^FDPASSED^FS^CI27
+^FT23,964^A0N,25,25^FH\^CI28^FDOperator:^FS^CI27
+^FT151,964^A0N,25,25^FH\^CI28^FD{OPERATOR}^FS^CI27
+^FT23,489^A0N,31,30^FH\^CI28^FD{DESCRIPTION}^FS^CI27
+^FT23,567^A0N,31,30^FH\^CI28^FDSequential number:^FS^CI27
+^FT23,602^A0N,31,30^FH\^CI28^FD{SN5}^FS^CI27
+^FT27,658^A0N,28,28^FH\^CI28^FDTest 1:^FS^CI27
+^FT27,685^A0N,23,23^FH\^CI28^FDMeasured press.:^FS^CI27
+^FT199,687^A0N,20,20^FH\^CI28^FD{RESPSET} mbar^FS^CI27
+^FT27,707^A0N,23,23^FH\^CI28^FDAllowed leak:^FS^CI27
+^FT199,709^A0N,20,20^FH\^CI28^FD{PMIN} mbar^FS^CI27
+^FT27,730^A0N,23,23^FH\^CI28^FDMeasured leak:^FS^CI27
+^FT187,731^A0N,20,20^FH\^CI28^FD{RESLEAK} mbar^FS^CI27
+^FT27,817^A0N,23,23^FH\^CI28^FDMeasure time:^FS^CI27
+^FT215,818^A0N,20,20^FH\^CI28^FD{TTEST} s^FS^CI27
+^FT26,773^A0N,23,23^FH\^CI28^FDFill time:^FS^CI27
+^FT215,770^A0N,20,20^FH\^CI28^FD{TFILL} s^FS^CI27
+^FT27,795^A0N,23,23^FH\^CI28^FDSettling time:^FS^CI27
+^FT215,794^A0N,20,20^FH\^CI28^FD{TSET} s^FS^CI27
+^FT136,658^A0N,28,28^FH\^CI28^FD{PTEST} mbar^FS^CI27
+^FT151,124^A0N,17,18^FH\^CI28^FDItaly^FS^CI27
+^FT27,893^A0N,23,23^FH\^CI28^FDTest date/time:^FS^CI27
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/MB1.prn b/config/label_templates/st-ten-7/MB1.prn
new file mode 100644
index 0000000..5322894
--- /dev/null
+++ b/config/label_templates/st-ten-7/MB1.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT137,147^A0B,42,41^FH\^CI28^FDMB 1^FS^CI27
+^FO148,86^GB8,61,4^FS
+^FT394,147^A0B,42,41^FH\^CI28^FDMB 1^FS^CI27
+^FO405,86^GB8,61,4^FS
+^FT239,34^A0R,42,41^FH\^CI28^FDMB 1^FS^CI27
+^FO220,33^GB8,61,4^FS
+^FT504,34^A0R,42,41^FH\^CI28^FDMB 1^FS^CI27
+^FO485,33^GB8,61,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO100,33^GB56,0,53^FS^LRN
+^LRY^FO357,33^GB56,0,53^FS^LRN
+^LRY^FO220,94^GB56,0,53^FS^LRN
+^LRY^FO485,94^GB56,0,53^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/MB2.prn b/config/label_templates/st-ten-7/MB2.prn
new file mode 100644
index 0000000..7807670
--- /dev/null
+++ b/config/label_templates/st-ten-7/MB2.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT137,147^A0B,42,41^FH\^CI28^FDMB 2^FS^CI27
+^FO148,86^GB8,61,4^FS
+^FT394,147^A0B,42,41^FH\^CI28^FDMB 2^FS^CI27
+^FO405,86^GB8,61,4^FS
+^FT239,34^A0R,42,41^FH\^CI28^FDMB 2^FS^CI27
+^FO220,33^GB8,61,4^FS
+^FT504,34^A0R,42,41^FH\^CI28^FDMB 2^FS^CI27
+^FO485,33^GB8,61,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO100,33^GB56,0,53^FS^LRN
+^LRY^FO357,33^GB56,0,53^FS^LRN
+^LRY^FO220,94^GB56,0,53^FS^LRN
+^LRY^FO485,94^GB56,0,53^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/MI1.prn b/config/label_templates/st-ten-7/MI1.prn
new file mode 100644
index 0000000..b902b4f
--- /dev/null
+++ b/config/label_templates/st-ten-7/MI1.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT137,137^A0B,42,41^FH\^CI28^FDMI 1^FS^CI27
+^FO148,86^GB8,61,4^FS
+^FT394,137^A0B,42,41^FH\^CI28^FDMI 1^FS^CI27
+^FO405,86^GB8,61,4^FS
+^FT239,40^A0R,42,41^FH\^CI28^FDMI 1^FS^CI27
+^FO220,33^GB8,61,4^FS
+^FT506,44^A0R,42,41^FH\^CI28^FDMI 1^FS^CI27
+^FO487,35^GB8,61,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO100,33^GB56,0,53^FS^LRN
+^LRY^FO357,33^GB56,0,53^FS^LRN
+^LRY^FO220,94^GB56,0,53^FS^LRN
+^LRY^FO487,97^GB56,0,53^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/MI2.prn b/config/label_templates/st-ten-7/MI2.prn
new file mode 100644
index 0000000..277a080
--- /dev/null
+++ b/config/label_templates/st-ten-7/MI2.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT137,137^A0B,42,41^FH\^CI28^FDMI 2^FS^CI27
+^FO148,86^GB8,61,4^FS
+^FT394,137^A0B,42,41^FH\^CI28^FDMI 2^FS^CI27
+^FO405,86^GB8,61,4^FS
+^FT239,40^A0R,42,41^FH\^CI28^FDMI 2^FS^CI27
+^FO220,33^GB8,61,4^FS
+^FT506,44^A0R,42,41^FH\^CI28^FDMI 2^FS^CI27
+^FO487,35^GB8,61,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO100,33^GB56,0,53^FS^LRN
+^LRY^FO357,33^GB56,0,53^FS^LRN
+^LRY^FO220,94^GB56,0,53^FS^LRN
+^LRY^FO487,97^GB56,0,53^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/RB1.prn b/config/label_templates/st-ten-7/RB1.prn
new file mode 100644
index 0000000..4fc9930
--- /dev/null
+++ b/config/label_templates/st-ten-7/RB1.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT393,150^A0B,42,43^FH\^CI28^FDRB 1^FS^CI27
+^FO404,89^GB8,61,4^FS
+^FT138,150^A0B,42,43^FH\^CI28^FDRB 1^FS^CI27
+^FO149,89^GB8,61,4^FS
+^FT245,35^A0R,42,43^FH\^CI28^FDRB 1^FS^CI27
+^FO226,32^GB8,61,4^FS
+^FT501,35^A0R,42,43^FH\^CI28^FDRB 1^FS^CI27
+^FO484,32^GB8,61,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO356,32^GB56,0,56^FS^LRN
+^LRY^FO101,32^GB56,0,56^FS^LRN
+^LRY^FO226,94^GB56,0,56^FS^LRN
+^LRY^FO484,94^GB56,0,56^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/RB2.prn b/config/label_templates/st-ten-7/RB2.prn
new file mode 100644
index 0000000..051a31b
--- /dev/null
+++ b/config/label_templates/st-ten-7/RB2.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT393,150^A0B,42,43^FH\^CI28^FDRB 2^FS^CI27
+^FO404,89^GB8,61,4^FS
+^FT138,150^A0B,42,43^FH\^CI28^FDRB 2^FS^CI27
+^FO149,89^GB8,61,4^FS
+^FT245,35^A0R,42,43^FH\^CI28^FDRB 2^FS^CI27
+^FO226,32^GB8,61,4^FS
+^FT501,35^A0R,42,43^FH\^CI28^FDRB 2^FS^CI27
+^FO484,32^GB8,61,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO356,32^GB56,0,56^FS^LRN
+^LRY^FO101,32^GB56,0,56^FS^LRN
+^LRY^FO226,94^GB56,0,56^FS^LRN
+^LRY^FO484,94^GB56,0,56^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/RM1.prn b/config/label_templates/st-ten-7/RM1.prn
new file mode 100644
index 0000000..a1c1e06
--- /dev/null
+++ b/config/label_templates/st-ten-7/RM1.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT139,151^A0B,42,43^FH\^CI28^FDRM 1^FS^CI27
+^FO149,85^GB8,66,4^FS
+^FT245,26^A0R,42,43^FH\^CI28^FDRM 1^FS^CI27
+^FO226,29^GB8,66,4^FS
+^FT397,151^A0B,42,43^FH\^CI28^FDRM 1^FS^CI27
+^FO407,85^GB8,66,4^FS
+^FT503,26^A0R,42,43^FH\^CI28^FDRM 1^FS^CI27
+^FO484,29^GB8,66,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO101,29^GB56,0,56^FS^LRN
+^LRY^FO226,95^GB56,0,56^FS^LRN
+^LRY^FO359,29^GB56,0,56^FS^LRN
+^LRY^FO484,95^GB56,0,56^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-7/RM2.prn b/config/label_templates/st-ten-7/RM2.prn
new file mode 100644
index 0000000..12c54ca
--- /dev/null
+++ b/config/label_templates/st-ten-7/RM2.prn
@@ -0,0 +1,38 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW679
+^LL200
+^LS0
+^FT139,151^A0B,42,43^FH\^CI28^FDRM 2^FS^CI27
+^FO149,85^GB8,66,4^FS
+^FT245,26^A0R,42,43^FH\^CI28^FDRM 2^FS^CI27
+^FO226,29^GB8,66,4^FS
+^FT397,151^A0B,42,43^FH\^CI28^FDRM 2^FS^CI27
+^FO407,85^GB8,66,4^FS
+^FT503,26^A0R,42,43^FH\^CI28^FDRM 2^FS^CI27
+^FO484,29^GB8,66,4^FS
+^LRY^FO2,1^GB676,0,198^FS^LRN
+^LRY^FO101,29^GB56,0,56^FS^LRN
+^LRY^FO226,95^GB56,0,56^FS^LRN
+^LRY^FO359,29^GB56,0,56^FS^LRN
+^LRY^FO484,95^GB56,0,56^FS^LRN
+^PQ1,0,1,Y
+^XZ
diff --git a/config/label_templates/st-ten-9/R5_30x17_203dpi.prn b/config/label_templates/st-ten-9/R5_30x17_203dpi.prn
new file mode 100644
index 0000000..4e45b02
--- /dev/null
+++ b/config/label_templates/st-ten-9/R5_30x17_203dpi.prn
@@ -0,0 +1,32 @@
+CT~~CD,~CC^~CT~
+^XA
+~TA000
+~JSN
+^LT0
+^MNW
+^MTT
+^PON
+^PMN
+^LH0,0
+^JMA
+^PR2,2
+~SD15
+^JUS
+^LRN
+^CI27
+^PA0,1,1,0
+^XZ
+^XA
+^MMT
+^PW256
+^LL144
+^LS0
+^FT156,132^BQN,2,3
+^FH\^FDLA,{PART}_{SN5}_{DATE}_{TIME}^FS
+^FT61,47^A0N,23,23^FH\^CI28^FD{PART}^FS^CI27
+^FT19,72^A0N,23,23^FH\^CI28^FDNum:{SN5}^FS^CI27
+^FT19,97^A0N,23,23^FH\^CI28^FD{DATE}^FS^CI27
+^FT19,122^A0N,23,23^FH\^CI28^FD{TIME}^FS^CI27
+^FO19,21^GFA,169,248,8,:Z64:eJxFz7ENAyEMBdCPrnCZEVgjRQQrUaY46RjtRmGElFec4vgbrNA82Rhji+qAnax60ar6pbulaAOkT7dzmsIxBX0v7X3Y2+zrRv656trf6BP9/T/rl+kLopyjQG6fs28fKgMeW1SoRV6Pyis7j56i0BdLa0Ec7g8asjdJ:20D6
+^PQ1,0,1,Y
+^XZ
diff --git a/config/machine_settings/defaults.ini b/config/machine_settings/defaults.ini
index 22004bd..5f35c00 100644
--- a/config/machine_settings/defaults.ini
+++ b/config/machine_settings/defaults.ini
@@ -11,12 +11,13 @@ barcode_recipe_selection: absent
; label_printer: present
; extra_label_printer: absent
; multicomp: present
-; neo_pixels: present
+; neo_pixels: absent
; remote_api: present
-; screwdriver: present
-; uvc_camera: present
-; vision_saver: present
-; vision: present
+; screwdriver: absent
+; uvc_camera: absent
+; vision_saver: absent
+; vision: absent
+; external_flush_blow: absent # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH
[galaxy_camera]
horizontal_resolution: 2448
@@ -102,6 +103,7 @@ cliente: specificare cliente
part_number: specificare part number
dimensione_lotto_abilitata: x
dimensione_lotto: 0
+richiedi_inserimento_scarto:
verifica_connettore_abilitata: x
connettore: SCRx
verifica_codice_a_barre_abilitata:
@@ -109,9 +111,6 @@ codice_a_barre:
avvitatura_abilitata:
viti: 0
istruzione_abilitata:
-numero nastri (n):0
-numero sensori anello (sa):0
-numero sensori presenza (sp):0
verifica_resistenza_connettore_abilitata: x
scala_resistenza: 500
@@ -120,6 +119,14 @@ tolleranza_resistenza_pos: 10
tolleranza_resistenza_neg: 5
prova_tenuta_abilitata: x
warning_img:
+
+#TECNA RECIPE PARAMETERS
+pid_mode: 0 # 0=FAST 1=MEDIUM 2=SLOW 4 = FIXED 5 = AUTOMATIC 6 = FLOW 7 = LEAK WITH FLOW
+pid_level: 1
+pid_speed: 1
+tester_discharge_enable: no
+pid_pressure_correction: 110
+
tempo_pre_riempimento: 0
pressione_pre_riempimento: 1000
tempo_riempimento: 10
@@ -132,7 +139,9 @@ pressione_di_test: 1111
pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
-config_elettrovalvole: 0
+canale_di_prova: 0
+tempo_soffiaggio_esterno: 3
+tempo_svuotamento_esterno: 2
prova_tenuta_abilitata_2:
tempo_pre_riempimento_2: 0
pressione_pre_riempimento_2: 1000
@@ -146,7 +155,9 @@ pressione_di_test_2: 2222
pressione_di_test_delta_massimo_2: 200
tempo_svuotamento_2: 1
pressione_svuotamento_2: 100
-config_elettrovalvole_2: 0
+tempo_soffiaggio_esterno_2: 3
+tempo_svuotamento_esterno_2: 2
+canale_di_prova_2: 0
test_visione_abilitato:
ricetta_visione: termorestringente_923578.ini
stampa_etichetta_abilitata: x
@@ -165,8 +176,8 @@ test_time: 10
test_pressure_qneg: 5
test_pressure: 9000
test_pressure_qpos: 5
-flush_time: 1
-flush_pressure: 100
+flush_time: 0
+flush_pressure: 0
[autotest_resistance]
enabled: false
diff --git a/config/machine_settings/hostnames.ini b/config/machine_settings/hostnames.ini
index 819d1f9..708b7ee 100644
--- a/config/machine_settings/hostnames.ini
+++ b/config/machine_settings/hostnames.ini
@@ -7,3 +7,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
+ST-TEN-9: st-ten-9
diff --git a/config/machine_settings/mino.ini b/config/machine_settings/mino.ini
deleted file mode 100644
index e847a1d..0000000
--- a/config/machine_settings/mino.ini
+++ /dev/null
@@ -1,29 +0,0 @@
-[machine]
-description = MINO
-
-[hardware_config]
-archive_synchronizer: present
-galaxy_camera: absent
-label_printer: present
-multicomp: present
-neo_pixels: present
-remote_api: present
-screwdriver: present
-tecna_t3: present
-uvc_camera: present
-vision_saver: present
-vision: present
-
-[tecna_t3]
-model: t3l
-port: /dev/ttyUSB0
-
-[multicomp]
-port: /dev/ttyACM0
-
-[neo_pixels]
-port: /dev/ttyACM1
-
-[archive_synchronizer]
-poll_time: 6
-hold_time: 1
diff --git a/config/machine_settings/neo-dl.ini b/config/machine_settings/neo-dl.ini
deleted file mode 100644
index d25e6f5..0000000
--- a/config/machine_settings/neo-dl.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-[machine]
-description = NEO-DL
-
-[hardware_config]
-archive_synchronizer: absent
-galaxy_camera: present
-label_printer: present
-neo_pixels: present
-remote_api: absent
-tecna_t3: present
-vision_saver: present
-vision: present
-
-[tecna_t3]
-port: /dev/ttyUSB0
-
-[neo_pixels]
-port: /dev/ttyACM0
diff --git a/config/machine_settings/st-ten-1-linux.ini b/config/machine_settings/st-ten-1-linux.ini
new file mode 100644
index 0000000..ca9bcc0
--- /dev/null
+++ b/config/machine_settings/st-ten-1-linux.ini
@@ -0,0 +1,62 @@
+[machine]
+description = ST-TEN-2 - COLLAUDO TUBI RISCALDATI VOLPIANO
+
+[hardware_config]
+archive_synchronizer: present
+label_printer: present
+remote_api: absent
+tecna_t3: present
+
+[digital_io]
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+id_flush_blow: USB-5860,BID#0
+blow_on: 0 # INPUT VALVE TO SERVICE AIR
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:2 # CLEAN INDICATOR
+test_on_led:3 # LEAK TEST ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
+
+[tecna_t3]
+port: /dev/ttyUSB0
+
+[recipe]
+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: 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
+canale_di_prova: 0
+tester_discharge_enable: yes
+
+[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-1.ini b/config/machine_settings/st-ten-1.ini
index 0a022fa..8620df1 100644
--- a/config/machine_settings/st-ten-1.ini
+++ b/config/machine_settings/st-ten-1.ini
@@ -3,7 +3,7 @@ description = ST-TEN-1
[hardware_config]
archive_synchronizer: present
-; galaxy_camera: present
+# galaxy_camera: present
uvc_camera: present
label_printer: present
neo_pixels: present
@@ -31,12 +31,10 @@ platform: windows
printer: zd420
[recipes_defaults]
-
-
codice_ricetta: specificare ricetta
cliente: IVECO
part_number: specificare part number
-config_elettrovalvole: 0
+canale_di_prova: 0
warning_img:
dimensione_lotto_abilitata:
@@ -82,14 +80,16 @@ descrizione: inserire descrizione ricetta
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_time: 10
-test_pressure_qneg: 10
test_pressure: 7000
-test_pressure_qpos: 5
+test_time: 10
+test_pressure_qpos: 10 #Q+ Upper test leak limit
+test_pressure_qneg: 20 #Q- Lower test leak limit
+test_pressure_tt_qpos: 1 # 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-linux.ini b/config/machine_settings/st-ten-2-linux.ini
new file mode 100644
index 0000000..f08d687
--- /dev/null
+++ b/config/machine_settings/st-ten-2-linux.ini
@@ -0,0 +1,67 @@
+[machine]
+description = ST-TEN-2 - COLLAUDO TUBI RISCALDATI VOLPIANO
+
+[hardware_config]
+archive_synchronizer: present
+label_printer: present
+multicomp: present
+remote_api: absent
+tecna_t3: present
+
+[digital_io]
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+id_flush_blow: USB-5860,BID#0
+blow_on: 0 # INPUT VALVE TO SERVICE AIR
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:2 # CLEAN INDICATOR
+test_on_led:3 # LEAK TEST ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
+
+[tecna_t3]
+port: /dev/ttyUSB0
+
+[multicomp]
+port: COM10
+4wire: enabled
+
+[recipe]
+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: 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
+canale_di_prova: 0
+tester_discharge_enable: yes
+
+[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-2.ini b/config/machine_settings/st-ten-2.ini
index 621a3ef..66f2020 100644
--- a/config/machine_settings/st-ten-2.ini
+++ b/config/machine_settings/st-ten-2.ini
@@ -8,6 +8,15 @@ multicomp: present
remote_api: absent
tecna_t3: present
+[digital_io]
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+id_flush_blow: USB-5860,BID#0
+blow_on: 0 # INPUT VALVE TO SERVICE AIR
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:2 # CLEAN INDICATOR
+test_on_led:3 # LEAK TEST ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
+
[tecna_t3]
port: COM6
@@ -38,7 +47,8 @@ pressione_di_test: 15000
pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
-config_elettrovalvole: 0
+canale_di_prova: 0
+tester_discharge_enable: yes
[autotest_leak]
enabled: true
diff --git a/config/machine_settings/st-ten-3.ini b/config/machine_settings/st-ten-3.ini
index 9480412..115ad9b 100644
--- a/config/machine_settings/st-ten-3.ini
+++ b/config/machine_settings/st-ten-3.ini
@@ -38,4 +38,23 @@ pressione_di_test: 15000
pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
-config_elettrovalvole: 0
+canale_di_prova: 0
+tester_discharge_enable: yes
+
+[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: 1 #Q+ Upper test leak limit
+test_pressure_qneg: 10 #Q- Lower test leak limit
+test_pressure_tt_qpos: 1 # 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..f088d6f 100644
--- a/config/machine_settings/st-ten-4.ini
+++ b/config/machine_settings/st-ten-4.ini
@@ -1,31 +1,80 @@
[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
+canale_di_prova: 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
+canale_di_prova_2: 2
+modello_etichetta: EtichettaR5_Montaggio_1prova.prn
+pid_pressure_correction: 140
+
+[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: 3 #Q+ Upper test leak limit (negative mbar)
+test_pressure_qneg: 15 #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 228f784..578e8f4 100644
--- a/config/machine_settings/st-ten-5.ini
+++ b/config/machine_settings/st-ten-5.ini
@@ -9,7 +9,9 @@ extra_label_printer: present
remote_api: absent
tecna_t3: present
digital_io: present
+digital_io_flush_blow: present
barcode_recipe_selection: present
+external_flush_blow: present # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH
show_instructions: yes
[tecna_t3]
@@ -33,14 +35,20 @@ printer: xlp504
[digital_io]
id: USB-5862,BID#0
+[digital_io_flush_blow]
+id: USB-5860,BID#0
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+blow_on: 0 # INPUT VALVE TO SERVICE AIR
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:2 # CLEAN INDICATOR
+ch1_led:3 # CHANNEL 1 ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
[recipes_defaults]
-
-
codice_ricetta: specificare ricetta
cliente: IVECO
part_number: specificare part number
-config_elettrovalvole: 0
+canale_di_prova: 0
warning_img:
dimensione_lotto_abilitata:
@@ -90,10 +98,12 @@ 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_time: 10
test_pressure_qpos: 5
+test_pressure_qneg: 17
+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-6.ini b/config/machine_settings/st-ten-6.ini
index 46555b6..21d794d 100644
--- a/config/machine_settings/st-ten-6.ini
+++ b/config/machine_settings/st-ten-6.ini
@@ -11,8 +11,10 @@ tecna_t3: present
vision_saver: absent
vision: absent
screwdriver: absent
-digital_io: present
+digital_io_flush_blow: present
second_leak_test: present
+external_flush_blow: present # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH
+dual_channel: present
[tecna_t3]
port: COM4
@@ -25,8 +27,17 @@ port: COM5
platform: windows
printer: zd421
-[digital_io]
+[digital_io_flush_blow]
id: USB-5860,BID#0
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+blow_on: 3 # INPUT VALVE TO SERVICE AIR
+out_channel_select: 2 # AIR OUT VALVE (0=CH1, 1=CH2)
+in_channel_select: 0 # AIR IN VALVE (0=CH1, 1=CH2)
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:7 # CLEAN INDICATOR
+ch1_led:6 # CHANNEL 1 ACTIVE INDICATOR
+ch2_led:5 # CHANNEL 2 ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
[recipe]
recipe_name_field: codice_ricetta
@@ -36,6 +47,7 @@ description_field: descrizione
[recipes_defaults]
dimensione_lotto_abilitata:
+tempo_soffiaggio: 5
tempo_pre_riempimento: 0
pressione_pre_riempimento: 1000
tempo_riempimento: 10
@@ -48,7 +60,7 @@ pressione_di_test: 7000
pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
-config_elettrovalvole: 1
+canale_di_prova: 0
prova_tenuta_abilitata_2:
tempo_pre_riempimento_2: 0
pressione_pre_riempimento_2: 1000
@@ -62,7 +74,7 @@ pressione_di_test_2: 15000
pressione_di_test_delta_massimo_2: 30
tempo_svuotamento_2: 1
pressione_svuotamento_2: 100
-config_elettrovalvole_2: 2
+canale_di_prova_2: 1
modello_etichetta: EtichettaR5_Montaggio_1prova.prn
[autotest_leak]
@@ -77,8 +89,8 @@ 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_qpos: 1 # 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
+chan_sel: 0
\ No newline at end of file
diff --git a/config/machine_settings/st-ten-7.ini b/config/machine_settings/st-ten-7.ini
index 3b3e1f8..c95fc66 100644
--- a/config/machine_settings/st-ten-7.ini
+++ b/config/machine_settings/st-ten-7.ini
@@ -5,65 +5,82 @@ description = ST-TEN-7 SECONDO BANCO IVECO DAILY ELETTRICO
archive_synchronizer: present
uvc_camera: absent
label_printer: present
-neo_pixels: present
+extra_label_printer: present
remote_api: absent
tecna_t3: present
-vision_saver: absent
-vision: absent
-screwdriver: absent
-digital_io: present
-second_leak_test: present
+digital_io: absent
+barcode_recipe_selection: present
+show_instructions: no
[tecna_t3]
port: COM4
model: t3l
-[neo_pixels]
-port: COM5
+[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
-[digital_io]
-id: USB-5860,BID#0
+[extra_label_printer]
+platform: windows
+printer: zt231
-[recipe]
-recipe_name_field: codice_ricetta
-part_number_field: codice_prodotto
-label_template_field: modello_etichetta
-description_field: descrizione
+
+[digital_io]
+id: USB-5862,BID#0
[recipes_defaults]
+
+
+codice_ricetta: specificare ricetta
+cliente: IVECO
+part_number: specificare part number
+canale_di_prova: 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: 1000
-tempo_riempimento: 15
-tempo_assestamento: 15
-tempo_di_test: 10
+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: 7000
+pressione_di_test: 5000
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
+tempo_riempimento_2: 5
+tempo_assestamento_2: 5
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_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
-config_elettrovalvole_2: 2
-modello_etichetta: EtichettaR5_Montaggio_1prova.prn
+
+stampa_etichetta_abilitata: x
+modello_etichetta: ETA30x16_203dpi.prn
+descrizione: inserire descrizione ricetta
[autotest_leak]
enabled: true
@@ -73,10 +90,12 @@ filling_time: 15
settling_time: 10
settling_pressure_min_percent: 5
settling_pressure_max_percent: 5
+test_pressure: 5000
test_time: 10
-test_pressure_qneg: 35
-test_pressure: 15000
-test_pressure_qpos: 5
+test_pressure_qpos: 7
+test_pressure_qneg: 17
+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-8.ini b/config/machine_settings/st-ten-8.ini
index f9d764b..df3ce56 100644
--- a/config/machine_settings/st-ten-8.ini
+++ b/config/machine_settings/st-ten-8.ini
@@ -12,9 +12,11 @@ vision_saver: absent
vision: absent
screwdriver: absent
digital_io: present
-second_leak_test: absent
+barcode_recipe_selection: present
fixture_id: present
discard_box: present
+enforce_piece_removal: yes
+external_flush_blow: present # EXTERNAL BOX CONTROLLING MULTI-CHANNEL TEST (IF PRESENT), BLOW-CLEANING AND EXTERNAL FLUSH
[tecna_t3]
port: COM4
@@ -25,8 +27,20 @@ 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
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+id_flush_blow: USB-5860,BID#0
+blow_on: 3 # INPUT VALVE TO SERVICE AIR
+out_channel_select: 2 # AIR OUT VALVE (0=CH1, 1=CH2)
+in_channel_select: 0 # AIR IN VALVE (0=CH1, 1=CH2)
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:7 # CLEAN INDICATOR
+ch1_led:6 # CHANNEL 1 ACTIVE INDICATOR
+ch2_led:5 # CHANNEL 2 ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
+
+# OUTPUT MAP FOR FIXTURE CONNECTOR
+id_fixture: USB-5862,BID#0
+discard_idx:12 # BIT NUMBER OF THE I/0 MODULE USED FOR DISCARD SENSING
[fixture_rfid]
port: COM5
@@ -38,7 +52,8 @@ label_template_field: modello_etichetta
description_field: descrizione
[recipes_defaults]
-dimensione_lotto_abilitata:
+tester_discharge_enable: yes
+dimensione_lotto_abilitata: x
tempo_pre_riempimento: 0
pressione_pre_riempimento: 1000
tempo_riempimento: 15
@@ -51,7 +66,7 @@ pressione_di_test: 7000
pressione_di_test_delta_massimo: 30
tempo_svuotamento: 1
pressione_svuotamento: 100
-config_elettrovalvole: 1
+canale_di_prova: 1
prova_tenuta_abilitata_2:
tempo_pre_riempimento_2: 0
pressione_pre_riempimento_2: 1000
@@ -65,21 +80,24 @@ pressione_di_test_2: 15000
pressione_di_test_delta_massimo_2: 30
tempo_svuotamento_2: 1
pressione_svuotamento_2: 100
-config_elettrovalvole_2: 2
+canale_di_prova_2: 2
modello_etichetta: EtichettaR5_Montaggio_1prova.prn
+pid_pressure_correction: 110
[autotest_leak]
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_qneg: 35
-test_pressure: 15000
-test_pressure_qpos: 5
+test_pressure_qpos: 10 #Q+ Upper test leak limit
+test_pressure_qneg: 30 #Q- Lower test leak limit
+test_pressure_tt_qpos: 1 # 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-9.ini b/config/machine_settings/st-ten-9.ini
new file mode 100644
index 0000000..f16601c
--- /dev/null
+++ b/config/machine_settings/st-ten-9.ini
@@ -0,0 +1,83 @@
+[machine]
+description = ST-TEN-9 SATIL SRL - BANCO PROVA TENUTA 10 BAR
+
+[hardware_config]
+archive_synchronizer: absent
+label_printer: present
+remote_api: absent
+tecna_t3: absent
+furness_controls: present
+
+[archive_synchronizer]
+archive_endpoint: https://satilportal.it/api/st-ten-save/
+poll_time: 60
+hold_time: 1
+
+[furness_controls]
+port: COM3
+model: fco730
+
+[label_printer]
+platform: windows
+printer: zd421
+
+[digital_io]
+# OUTPUT MAP FOR EXTERNAL FLUSH/BLOW UNIT
+id_flush_blow: USB-5860,BID#0
+blow_on: 3 # INPUT VALVE TO SERVICE AIR
+out_channel_select: 2 # AIR OUT VALVE (0=CH1, 1=CH2)
+in_channel_select: 0 # AIR IN VALVE (0=CH1, 1=CH2)
+flush_on: 1 # OUTPUT VALVE TO DIRT COLLECTOR
+blow_led:7 # CLEAN INDICATOR
+ch1_led:6 # CHANNEL 1 ACTIVE INDICATOR
+ch2_led:5 # CHANNEL 2 ACTIVE INDICATOR
+flush_led:4 # FLUSH INDICATOR
+
+# OUTPUT MAP FOR FIXTURE CONNECTOR
+id_fixture: USB-5862,BID#0
+discard_idx:12 # 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]
+tester_discharge_enable: yes
+dimensione_lotto_abilitata:
+tempo_pre_riempimento: 0
+pressione_pre_riempimento: 0
+tempo_riempimento: 5
+tempo_assestamento: 10
+tempo_di_test: 10
+percentuale_minima_pressione_assestamento: 5
+percentuale_massima_pressione_assestamento: 5
+pressione_di_test_delta_minimo: 20 # +mbar
+pressione_di_test: 5000 # mbar
+pressione_di_test_delta_massimo: 20 # -mbar
+tempo_svuotamento: 1
+pressione_svuotamento: 100
+canale_di_prova: 1
+modello_etichetta: R5_30x17_203dpi.prn
+
+[autotest_leak]
+enabled: true
+pre_filling_time: 0
+pre_filling_pressure: 0
+filling_time: 10
+settling_time: 10
+settling_pressure_min_percent: 5
+settling_pressure_max_percent: 5
+test_pressure: 5000
+test_time: 10
+test_pressure_qpos: 10 #Q+ Upper test leak limit
+test_pressure_qneg: 30 #Q- Lower test leak limit
+test_pressure_tt_qpos: 1 # 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
diff --git a/config/machine_settings/vm.ini b/config/machine_settings/vm.ini
deleted file mode 100644
index 1dd03bb..0000000
--- a/config/machine_settings/vm.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[machine]
-description = VM
-
-[tecna_t3]
-port: COM4
-
-[neo_pixels]
-port: COM3
diff --git a/designer.sh b/designer.sh
index 9a38387..1fdd748 100755
--- a/designer.sh
+++ b/designer.sh
@@ -1,7 +1 @@
-#!/bin/bash -x
-cd "$(dirname "$0")"
-source "./venv/bin/activate" || source "./venv/Scripts/activate" || :
-#python3 -m pip install --upgrade qt5-tools
-#"$(python3 -c "import sys; print(sys.path[-1])")/qt5_applications/Qt/bin/designer" $*
-$(pwd)/venv/lib/python3.9/site-packages/qt5_applications/Qt/bin/designer $*
-#$(pwd)/venv/lib/python3.8/site-packages/qt5_applications/Qt/bin/designer $*
+pyqt5-tools designer
diff --git a/designer_win.bat b/designer_win.bat
index ce9cbec..6784207 100644
--- a/designer_win.bat
+++ b/designer_win.bat
@@ -1 +1 @@
-.\venv\Lib\site-packages\qt5_applications\Qt\bin\designer.exe
+pyqt5-tools designer
\ No newline at end of file
diff --git a/init.sh b/init.sh
index fc9221d..9b612e6 100755
--- a/init.sh
+++ b/init.sh
@@ -4,11 +4,11 @@ here="$(realpath "$(dirname "$0")")"
cd "$here"
echo "---------- initialize venv ----------"
-sudo apt-get install python3-venv
+sudo apt-get install python3 python3-venv python-is-python3 python3-pip
lsof "./venv/bin/python" | awk 'NR > 1 {print $2}' | xargs kill || :
lsof "./venv/Scripts/activate" | awk 'NR > 1 {print $2}' | xargs kill || :
python="python"
-"${python}" -m pip install --upgrade pip
+#"${python}" -m pip install --upgrade pip
"${python}" -m venv venv
source "./venv/bin/activate" || source "./venv/Scripts/activate" || :
"${python}" -m pip install --upgrade pip
@@ -42,7 +42,7 @@ source "./venv/bin/activate" || source "./venv/Scripts/activate" || :
# DOCKER_IMAGE="ubuntu:18.04" DOCKER_TARGETS=libedgetpu make docker-build
# sudo make install
# cd "$here"
-#echo "---------- install gxlpy ----------"
+#echo "---------- install gxipy ----------"
#sudo apt-get install -y g++ libc-bin
#mkdir -p "$here/tmp"
#cd "$here/tmp"
diff --git a/init_win.bat b/init_win.bat
index b266984..c636374 100644
--- a/init_win.bat
+++ b/init_win.bat
@@ -9,6 +9,9 @@ cd tmp
:: Advantech XNAVI
Invoke-WebRequest -uri "https://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-2BZC0F1" -usebasicparsing -outfile xnavi.zip
+Expand-Archive .\xnavi.zip
+cd xnavi
+./xnavi.exe
:: GXIPY
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/make_desktop_file_noautotest.bat b/make_desktop_file_noautotest.bat
new file mode 100644
index 0000000..64137d9
--- /dev/null
+++ b/make_desktop_file_noautotest.bat
@@ -0,0 +1,9 @@
+set SCRIPT="%TEMP%\%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.vbs"
+echo Set oWS = WScript.CreateObject("WScript.Shell") >> %SCRIPT%
+echo sLinkFile = "%USERPROFILE%\Desktop\NO AUTOTEST.lnk" >> %SCRIPT%
+echo Set oLink = oWS.CreateShortcut(sLinkFile) >> %SCRIPT%
+echo oLink.TargetPath = "%userprofile%\PycharmProjects\st-ten-1\runme_noautotest.bat" >> %SCRIPT%
+echo oLink.IconLocation = "%userprofile%\PycharmProjects\st-ten-1\src\ui\imgs\neo_red.ico"
+echo oLink.Save >> %SCRIPT%
+cscript /nologo %SCRIPT%
+del %SCRIPT%
diff --git a/open_osk.bat b/open_osk.bat
new file mode 100644
index 0000000..0816ab6
--- /dev/null
+++ b/open_osk.bat
@@ -0,0 +1 @@
+osk
diff --git a/runme.bat b/runme.bat
index 2bd6bf6..f2ba63c 100644
--- a/runme.bat
+++ b/runme.bat
@@ -1,4 +1,4 @@
echo on
SET mypath=%~dp0
cd %mypath%
-.\venv\Scripts\activate.bat && python -O "./src/main.py" --no-edgetpu --no-tflite
+.\venv\Scripts\activate.bat && python -O "./src/main.py"
diff --git a/runme_noautotest.bat b/runme_noautotest.bat
index 0e1d578..b689c06 100644
--- a/runme_noautotest.bat
+++ b/runme_noautotest.bat
@@ -1,4 +1,4 @@
echo on
SET mypath=%~dp0
cd %mypath%
-.\venv\Scripts\activate.bat && python -O "./src/main.py" --no-edgetpu --no-tflite --no-autotest
+.\venv\Scripts\activate.bat && python -O "./src/main.py" --no-autotest
diff --git a/src/components/__init__.py b/src/components/__init__.py
index 973d595..962bcd5 100644
--- a/src/components/__init__.py
+++ b/src/components/__init__.py
@@ -9,8 +9,9 @@ from .remote_api import RemoteAPI
from .serial_label_printer import Serial_Label_Printer
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
+from .furness_controls_leak_tester import FurnessControlsLeakTester
if "--vision" in sys.argv:
from .galaxy_camera import GalaxyCamera
from .neo_pixels import NeoPixels
diff --git a/src/components/archive_synchronizer.py b/src/components/archive_synchronizer.py
index 1b34baf..9bb7cbc 100644
--- a/src/components/archive_synchronizer.py
+++ b/src/components/archive_synchronizer.py
@@ -43,6 +43,8 @@ class ArchiveSynchronizer(Component):
record.archived = self.remote_archive(record) is True
if record.uploaded is not True:
record.uploaded = self.remote_store(record) is True
+ else:
+ self.log.info("simulated archive synchronizer cycle")
record.save()
if self.hold_time > 0:
QThread.msleep(self.hold_time)
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/furness_controls_fco730_registers.py b/src/components/furness_controls_fco730_registers.py
new file mode 100644
index 0000000..381f29a
--- /dev/null
+++ b/src/components/furness_controls_fco730_registers.py
@@ -0,0 +1,82 @@
+registers = {
+ "commands": {
+ "program_data": b'A000',
+ "product_data": b'B050',
+ "function_data": b'D000',
+ "counters": b'E000',
+ "change_cur_prod": b'F000',
+ "change_cur_prod_50": b'F050',
+ "start_test": b'G000',
+ "reset_test": b'H000',
+ "version_num_range": b'I000',
+ "reset_counters": b'J000',
+ "self_check": b'K000',
+ "last_test_result": b'L000',
+ "current_status": b'M000',
+ "zero_pressure": b'O000',
+ "security_data": b'P000',
+ "printer_settings": b'S000',
+ "comm_settings": b'x000'
+ },
+ "product_tags": {
+ "product_id": b'a',
+ "test_pressure": b'b',
+ "tolerance": b'c',
+ "+fail": b'd',
+ "-fail": b'e',
+ "fill_time": b'f',
+ "stab_time": b'g',
+ "test_time": b'h',
+ "prefill_time": b'l',
+ "vent_time": b'm',
+ "test_type": b'n',
+ "fail_high": b'o',
+ "fail_low": b'p',
+ "outputs_a_h": b'q',
+ "prefill_pressure": b'r',
+ },
+
+ "program_tags": {
+ "leak_units": b'a',
+ "press_units": b'b',
+ "leak_at_eot": b'c',
+ "product": b'l',
+ },
+ "enums": {
+ "status_status": {
+ '0': 'ready_to_start',
+ '1': 'fault',
+ '2':'awaiting_reset',
+ '3': 'pressure_high',
+ '4': 'pressure_low',
+ '5': 'testing',
+ },
+ "status_current_stage": {
+ '0': 'STANDBY',
+ '1': 'RIEMPIMENTO',
+ '2': 'ASSESTAMENTO',
+ '3': 'MISURA',
+ '4': 'ATTESA RESET',
+ '5': 'ATTESA START',
+ '6': 'ERRORE',
+ '7': 'PRESSIONE ALTA',
+ '8': 'PRESSIONE BASSA',
+ '9': 'jig_delay',
+ '10': 'prefilling',
+ '11': 'SCARICO',
+ '12': 'reserverd',
+ '13': 'sequence_delay',
+ '14': 'jig_open'
+ },
+ "status_result":{
+ '0': 'PASSED',
+ '1': 'NEGATIVE FAIL',
+ '2': 'POSITIVE FAIL',
+ '3': 'RESERVED',
+ '4': 'PRESSURE GROSS FAIL',
+ '5': 'RESET DURING TEST',
+ '6': 'GLOBAL FAIL',
+ }
+ }
+
+}
diff --git a/src/components/furness_controls_fco780_registers.py b/src/components/furness_controls_fco780_registers.py
new file mode 100644
index 0000000..c93ddae
--- /dev/null
+++ b/src/components/furness_controls_fco780_registers.py
@@ -0,0 +1,45 @@
+registers = {
+ "commands": {
+ "program_data": b'A000',
+ "product_data": b'B050',
+ "function_data": b'D000',
+ "counters": b'E000',
+ "change_cur_prod": b'F000',
+ "change_cur_prod_50": b'F050',
+ "start_test": b'G000',
+ "reset_test": b'H000',
+ "version_num_range": b'I000',
+ "reset_counters": b'J000',
+ "self_check": b'K000',
+ "last_test_result": b'L000',
+ "current_status": b'M000',
+ "zero_pressure": b'O000',
+ "security_data": b'P000',
+ "printer_settings": b'S000',
+ "comm_settings": b'x000'
+ },
+ "product_tags": {
+ "product_id": b'a',
+ "test_pressure": b'b',
+ "tolerance": b'c',
+ "+fail": b'd',
+ "-fail": b'e',
+ "fill_time": b'f',
+ "stab_time": b'g',
+ "test_time": b'h',
+ "prefill_time": b'l',
+ "vent_time": b'm',
+ "test_type": b'n',
+ "fail_high": b'o',
+ "fail_low": b'p',
+ "outputs_a_h": b'q',
+ "prefill_pressure": b'r',
+ },
+
+ "program_tags": {
+ "leak_units": b'a',
+ "press_units": b'b',
+ "leak_at_eot": b'c',
+ "product": b'l',
+ }
+}
diff --git a/src/components/furness_controls_leak_tester.py b/src/components/furness_controls_leak_tester.py
new file mode 100644
index 0000000..f113daa
--- /dev/null
+++ b/src/components/furness_controls_leak_tester.py
@@ -0,0 +1,291 @@
+import re
+import sys
+import time
+from collections import OrderedDict
+
+from PyQt5.QtCore import QMutex
+
+from components.component import Component
+from components.furness_controls_fco730_registers import registers as fco730_registers
+from components.furness_controls_fco780_registers import registers as fco780_registers
+
+if "--sim-furness-controls" in sys.argv:
+ from components.dummies.serial import serial
+else:
+ import serial
+
+ETX = b'\x03'
+EOT = b'\x04'
+ENQ = b'\x05'
+ACK = b'\x06'
+NACK = b'\x15'
+
+
+class FurnessControlsLeakTester(Component):
+
+ def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True):
+ super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
+ self.enums = None
+ self.current_status = None
+ self.product_tags = None
+ self.bytesize = None
+ self.timeout = None
+ self.parity = None
+ self.conn = None
+ self.lock = QMutex()
+ self.stopbits = None
+ self.baudrate = None
+ self.port = None
+ self.model = None
+ self.settings = None
+ self.commands = None
+ self.id1 = b'0'
+ self.id2 = b'1'
+
+ def config_changed(self):
+ super().config_changed()
+ self.model = self.config[self.name]["model"].lower()
+ if self.model == "fco730":
+ self.commands = fco730_registers["commands"]
+ self.product_tags = fco730_registers["product_tags"]
+ self.enums = fco730_registers["enums"]
+ else:
+ raise NotImplementedError(f"Furness Controls model {self.model!r} not implemented.")
+ self.port = self.config[self.name]["port"]
+ self.baudrate = 9600
+ self.stopbits = 1
+ self.parity = serial.PARITY_NONE
+ self.bytesize = serial.EIGHTBITS
+ self.timeout = 0.1
+ if self.conn is not None:
+ self.conn.close()
+ self.conn = serial.Serial(
+ self.port,
+ baudrate=self.baudrate,
+ stopbits=self.stopbits,
+ parity=self.parity,
+ bytesize=self.bytesize,
+ timeout=self.timeout,
+ write_timeout=self.timeout,
+ )
+
+ def _convert_from_format(self, data, formatting=None, decoding_map=None):
+ if decoding_map is not None and data in decoding_map:
+ data = decoding_map[data]
+ if formatting is not None:
+ # units = self.units[formatting]
+ # data = [data * units[0], units[1]]
+ data = data * self.units[formatting][0]
+ return data
+
+ @Component.reconfig_on_error
+ def _get(self):
+ # READ INFO
+ current_status = self.get_status()
+ info = {
+ "Real time test pressure output": current_status["pressure_reading"],
+ "Real time differential pressure output": 0,
+ "Real time pressure line regulator": 0,
+ "Active alarm flags": 0,
+ "Active test program number": 0,
+ "Running test: active phase": current_status["current_stage"],
+ "Running test: measured leak": current_status["leak_reading"],
+ "Running test: test type": 0,
+ "Running test: sequence index": 0,
+ "Digital inputs status (mask)": 0,
+ }
+
+ if current_status['new_result_available'] == '1': # NEW TEST RESULT AVAILABLE
+ last_test_result = self.get_last_result() # READ RESULT TO RESET AVAILABLE FLAG
+ info.update({"Running test: result": last_test_result['status'],
+ "Running test: filling pressure": current_status["pressure_reading"],
+ "Running test: pressure at the end of settling": current_status["pressure_reading"],
+
+ })
+ 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])
+
+ def start_test(self, table=None):
+ self.log.info(f"starting test")
+ self.send_command("start_test")
+
+ def stop_test(self):
+ self.log.warning("resetting state...")
+ current_status = self.get_status()
+ if current_status['status'] in ('ready_to_start',):
+ self.log.info("ready to start")
+ elif current_status['status'] in ('pressure_high', 'pressure_low', 'fault'):
+ self.log.info(f"{current_status['status']}, performing self check to reset")
+ elif current_status['status'] == "testing":
+ self.log.info("stop running test")
+ self.send_command("reset_test")
+ else:
+ self.log.error(f"unknown state {current_status['status']}")
+
+ time.sleep(2)
+
+ def get_status(self):
+ status_str = str(self.send_enquiry("current_status"), encoding="ascii")
+ status_str += 'z' # dummy terminator
+ status_vars = OrderedDict(
+ {
+ 'a': 'counter',
+ 'b': 'product_number',
+ 'c': 'step_number',
+ 'd': 'new_result_available',
+ 'e': 'mode',
+ 'f': 'status',
+ 'g': 'pressure_reading',
+ 'h': 'pressure_units',
+ 'i': 'leak_reading',
+ 'j': 'leak_offset',
+ 'k': 'current_stage',
+ 'z': 'dummy'
+ })
+ status_decoded = {}
+ for tag, param in status_vars.items():
+ next_tag = list(status_vars)[list(status_vars.keys()).index(tag) + 1]
+ match = re.search(f"{tag}([0-9.-]+){next_tag}", status_str)
+ value = None
+ if match is not None:
+ value = match.group(1)
+ if param == 'status':
+ value = self.enums['status_status'][value]
+ elif param == 'current_stage':
+ value = self.enums['status_current_stage'][value]
+ elif param == 'pressure_reading':
+ value = f"{float(value) * 1000:.1f}"
+
+ status_decoded[param] = value
+ if next_tag == 'z':
+ break
+
+ return status_decoded
+
+ def get_last_result(self):
+ res_str = str(self.send_enquiry("last_test_result"), encoding="ascii")
+ res_str += 'z' # dummy terminator
+ status_vars = OrderedDict(
+ {
+ 'a': 'counter',
+ 'b': 'step_number',
+ 'c': 'product_number',
+ 'd': 'status',
+ 'z': 'dummy'
+ })
+ res_decoded = {}
+ for tag, param in status_vars.items():
+ next_tag = list(status_vars)[list(status_vars.keys()).index(tag) + 1]
+ match = re.search(f"{tag}([0-9.-]+){next_tag}", res_str)
+ value = None
+ if match is not None:
+ value = match.group(1)
+ if param == 'status':
+ value = self.enums['status_result'].get(value, 'NOK')
+
+ res_decoded[param] = value
+ if next_tag == 'z':
+ break
+
+ return res_decoded
+
+ def write_recipe(self, recipe, step, table=None):
+ # PREPARE DATA
+ product_id = '"' + recipe.part_number[:16] + '"'
+ product_id = product_id.encode("ascii")
+ test_press_bar = step.spec["test_pressure"] / 1000
+ prefill_press_bar = step.spec["pre_filling_pressure"] / 1000
+ tolerance = int(step.spec["settling_pressure_min_percent"])
+ fail_pos = (int(step.spec["test_pressure_qpos"]))
+ fail_neg = (int(step.spec["test_pressure_qneg"]))
+ fill_time = float(step.spec["filling_time"])
+ stab_time = float(step.spec["settling_time"])
+ test_time = float(step.spec["test_time"])
+ prefill_time = float(step.spec["pre_filling_time"])
+ vent_time = float(step.spec["flush_time"])
+ # SEND RECIPE PARAMETERS
+ self.send_command("change_cur_prod_50")
+ self.send_product_tag("product_id", product_id)
+ self.send_product_tag("prefill_pressure", f"{prefill_press_bar:2.3f}")
+ self.send_product_tag("test_pressure", f"{test_press_bar:2.3f}")
+ self.send_product_tag("tolerance", f"{tolerance:3.1f}")
+ self.send_product_tag("+fail", f"{fail_pos:3.1f}")
+ self.send_product_tag("-fail", f"{fail_neg:3.1f}")
+ self.send_product_tag("fill_time", f"{fill_time:3.1f}")
+ self.send_product_tag("stab_time", f"{stab_time:3.1f}")
+ self.send_product_tag("test_time", f"{test_time:3.1f}")
+ self.send_product_tag("prefill_time", f"{prefill_time:3.1f}")
+ self.send_product_tag("vent_time", f"{vent_time:3.1f}")
+ self.send_product_tag("fail_high", f"{fail_pos:3.1f}")
+ self.send_product_tag("fail_low", f"{fail_neg:3.1f}")
+ self.send_product_tag("outputs_a_h", f"{int(0b01000000)}")
+
+ self.get_last_result() # CLEAR POSSIBLE NEW RESULT AVAILABLE FLAG
+
+ def send_command(self, command):
+ if type(command) is str:
+ command = self.commands[command]
+ out_bytes = bytearray()
+ out_bytes.extend(EOT)
+ out_bytes.extend(self.id1)
+ out_bytes.extend(self.id2)
+ out_bytes.extend(command)
+ out_bytes.extend(ETX)
+ checksum = self.calc_checksum(out_bytes)
+ out_bytes.append(checksum)
+ self.lock.lock()
+ self.conn.write(out_bytes)
+ response = self.conn.read(1)
+ self.lock.unlock()
+ if response == ACK:
+ return True
+ else:
+ self.log.error(f"SEND COMMAND({command}):{response}")
+ return None
+
+ def send_enquiry(self, enquiry):
+ if type(enquiry) is str:
+ enquiry = self.commands[enquiry]
+ out_bytes = bytearray(EOT)
+ out_bytes.extend(self.id1)
+ out_bytes.extend(self.id2)
+ out_bytes.extend(enquiry)
+ out_bytes.extend(ENQ)
+ checksum = self.calc_checksum(out_bytes)
+ out_bytes.append(checksum)
+ self.lock.lock()
+ self.conn.write(out_bytes)
+ response = self.conn.read(100)
+ self.lock.unlock()
+ if len(response):
+ read_checksum = response[-1]
+ else:
+ read_checksum = None
+ calculated_checksum = self.calc_checksum(response[0:-1], start_idx=0)
+ if read_checksum != calculated_checksum:
+ self.log.error(f"ENQUIRY RESPONSE CHECKSUM:{read_checksum}!={calculated_checksum}")
+ return None
+ else:
+ response = response[:-2] # strip checksum & ETX
+ return response
+
+ def send_product_tag(self, tag, tag_data):
+ self.log.info(f"Sending tag:{tag}={tag_data}")
+ command = bytearray(self.commands["product_data"])
+ if type(tag_data) is str:
+ tag_data = bytearray(tag_data, encoding="ascii")
+ command.extend(self.product_tags[tag])
+ command.extend(tag_data)
+ self.send_command(command)
+
+ @staticmethod
+ def calc_checksum(data, start_idx=1):
+ checksum = 0
+ for i, data_byte in enumerate(data):
+ if i < start_idx:
+ continue # skip EOT
+ checksum = checksum ^ data_byte
+ return checksum
diff --git a/src/components/modbus_component.py b/src/components/modbus_component.py
index 0a33db6..1c34453 100644
--- a/src/components/modbus_component.py
+++ b/src/components/modbus_component.py
@@ -33,8 +33,8 @@ class ModbusComponent(Component):
self.stopbits = getattr(serial, self.config[self.name].get("stopbits", "stopbits_one").upper())
self.parity = getattr(serial, self.config[self.name].get("parity", "parity_none").upper())
self.bytesize = getattr(serial, self.config[self.name].get("bytesize", "eightbits").upper())
- self.byteorder = getattr(Endian, self.config[self.name].get("byteorder", "Big").title())
- self.wordorder = getattr(Endian, self.config[self.name].get("wordorder", "Little").title())
+ self.byteorder = getattr(Endian, self.config[self.name].get("byteorder", "Big").upper())
+ self.wordorder = getattr(Endian, self.config[self.name].get("wordorder", "Little").upper())
self.timeout = int(self.config[self.name].get("timeout", 1))
self.lock.lock()
self.client = ModbusClient(
diff --git a/src/components/multicomp_730424.py b/src/components/multicomp_730424.py
index 147f585..3fca333 100644
--- a/src/components/multicomp_730424.py
+++ b/src/components/multicomp_730424.py
@@ -1,6 +1,6 @@
import sys
-if "--sim-serial" in sys.argv:
+if "--sim-multicomp" in sys.argv:
from components.dummies.serial import serial
else:
import serial
diff --git a/src/components/os_label_printer.py b/src/components/os_label_printer.py
index 39d94f0..bc27dc4 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
@@ -34,8 +34,19 @@ class Os_Label_Printer(Component):
def print_label(self, template, context=None):
if context is None:
context = {}
+ custom_label_folder=f"config/label_templates/{str(self.config.machine_id)}/"
+ standard_label_folder=f"config/label_templates/"
+ if os.path.exists(custom_label_folder):
+ label_folder = custom_label_folder
+ else:
+ label_folder = standard_label_folder
+ label_path = label_folder+str(template)
+ if os.path.exists(label_path):
+ pass
+ else:
+ label_path = standard_label_folder+str(template)
# LOAD LABEL TEMPLATE
- with open(f"config/label_templates/{str(template)}", "r", errors="surrogateescape", encoding='iso-8859-1') as f:
+ with open(label_path, "r", errors="surrogateescape", encoding='iso-8859-1') as f:
label_file_contents = f.read()
# LABEL PRINT
#label = label.format(**context)
@@ -43,7 +54,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"))
@@ -64,16 +75,14 @@ class Os_Label_Printer(Component):
label_file = "tmp/label.prn"
with open(label_file, "w", errors="surrogateescape") as f:
f.write(label_file_contents)
- if self.platform == "windows":
+ if platform.system().lower() == "windows":
cmd = f'print /d:"{self.printer}" "{label_file}"'
- elif self.platform == "cups":
- cmd = f'lp -d "{self.printer}" "{label_file}"'
else:
- raise NotImplementedError(f"platform {self.platform!r} is not supported")
+ cmd = f'lp -d "{self.printer}" "{label_file}"'
if not self.simulate:
p = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True) # unsafe
if p.returncode != 0:
- self.log.exception(f"failed to print: returncode: {p.returncode}\noutput:\n{p.stdout}")
+ self.log.exception(f"failed to print: return code: {p.returncode}\noutput:\n{p.stdout}")
QMessageBox.critical(
None,
"Errore Stampante",
diff --git a/src/components/rfid.py b/src/components/rfid.py
deleted file mode 100644
index 69af776..0000000
--- a/src/components/rfid.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import ctypes
-import sys
-import platform
-from PyQt5.QtCore import QMutex, Qt, QTimer, pyqtSlot, pyqtSignal
-from .component import Component
-import nfc
-from nfc.clf import RemoteTarget
-
-
-
-is_win = platform.system() == "Windows"
-
-class RFID(Component):
- def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True):
- super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
- self.mutex = QMutex()
- self.simulate="--sim-rfid" in sys.argv
- self.clf = nfc.ContactlessFrontend()
-
- def open_device(self):
- self.clf.open('tty:USB0:pn532')
-
- def close_device(self):
- pass
-
- @pyqtSlot()
- def start(self):
- # ACQUISITION TIMER
- self.timer = QTimer()
- self.timer.setTimerType(Qt.PreciseTimer)
- self.timer.setInterval(int(1000 / 20))
- self.timer.timeout.connect(self.get)
- self.timer.start()
- super().start()
-
- @pyqtSlot()
- def get(self):
- data=None
- if data is not None:
- super()._get([data])
-
-
diff --git a/src/components/rfid_pn532.py b/src/components/rfid_pn532.py
new file mode 100644
index 0000000..fde6449
--- /dev/null
+++ b/src/components/rfid_pn532.py
@@ -0,0 +1,81 @@
+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"{'com'if self.is_win else 'tty'}:{self.config['fixture_rfid']['port']}: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 not self.simulate:
+ 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 93c45f2..b4143a7 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):
@@ -205,16 +205,15 @@ class TecnaMarpossProvasetT3(ModbusComponent):
# READ INFO
info = {r: self.read(r) for r in [
"Real time test pressure output",
+ "Real time differential pressure output",
"Real time pressure line regulator",
- #"Real time differential pressure output",
- #"Active alarm flags",
- #"Active test program number",
+ "Active alarm flags",
+ "Active test program number",
"Running test: active phase",
"Running test: test type",
- "Running test: measured leak",
"Running test: sequence index",
"Digital inputs status (mask)",
- "Digital outputs status (mask)",
+ # "Digital outputs status (mask)",
]}
if self.model == "t3p":
pass
@@ -272,6 +271,10 @@ class TecnaMarpossProvasetT3(ModbusComponent):
recipe_name += b"\x00" * (16 - len(recipe_name))
recipe_barcode = f"j{recipe.part_number}"[:16].encode("ascii")
recipe_barcode += b"\x00" * (24 - len(recipe_barcode))
+ test_flags = 0b0110100001010100 if (step.spec.get("autotest", False) in ["ko_check"]) else 0b0110000001010100
+ pid_mode = int(self.config["recipes_defaults"]["pid_mode"])<<4
+ test_flags = test_flags | pid_mode
+ pid_ramps=0b0000000000000000 | int(self.config["recipes_defaults"]["pid_level"])<<8 | int(self.config["recipes_defaults"]["pid_speed"])<<12
spec = {
"Flag: Instrument settings": 0b0000000000000000,
"Test program for read/write operation": table,
@@ -281,8 +284,7 @@ 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": 0b0110100001010100 if step.spec.get("autotest", False) in ("ok_check","ko_check") else 0b0110000001010100,
+ "Test flags": test_flags,
"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"],
@@ -295,6 +297,11 @@ class TecnaMarpossProvasetT3(ModbusComponent):
"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,
+ "RAMPS: T1 configuration": pid_ramps,
+ "PID: pressure correction": int(self.config["recipes_defaults"]["pid_pressure_correction"]),
+ "Various flags": 0b0000000000010000 if self.config["recipes_defaults"]["tester_discharge_enable"] == "yes" else 0b0000000000000000
+
}
if self.model == "t3p":
pass
@@ -305,7 +312,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 3b28ab0..93ac2e1 100644
--- a/src/components/tecna_marposs_provaset_t3l_registers.py
+++ b/src/components/tecna_marposs_provaset_t3l_registers.py
@@ -275,9 +275,7 @@ registers = {
# T1/Pr: Filling mode 0=TIME 1=PRESSURE (*)
# T1/Pr (T3LPQ) = 0 - 250 (seconds)
# T3/Q: Fail mode 0=TIME 1=PRESSURE (*)
- # PID MODE: 0=FAST 1=MEDIUM 2=SLOW 4 = FIXED 5 = AUTOMATIC 6 = FLOW 7 = LEAK WITH
- # -----
- # FLOW
+ # PID MODE: 0=FAST 1=MEDIUM 2=SLOW 4 = FIXED 5 = AUTOMATIC 6 = FLOW 7 = LEAK WITH FLOW
# P0-: 0= P0 pre-filling pressure is positive 1=P0 pre-filling pressure is negative (vacuum)
# Pr-: 0= Pr filling pressure is positive 1=Pr filling pressure is negative (vacuum)
# B: = beep (not used)
@@ -337,5 +335,7 @@ 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", }],
+ "RAMPS: T1 configuration": [755-1, {"dt": "16bit_uint", }],
+ "Various flags": [758-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 750e8bb..6714b7e 100644
--- a/src/components/tecna_marposs_provaset_t3p_registers.py
+++ b/src/components/tecna_marposs_provaset_t3p_registers.py
@@ -274,7 +274,7 @@ registers = {
"PB - Minimum burst pressure": [743 - 1, {"dt": "16bit_uint", "f": 23, }],
"BD - Burst gap / PD - Delta Aperture": [744 - 1, {"dt": "16bit_uint", "f": 23, }],
"FSL - Discharge limit": [745 - 1, {"dt": "16bit_uint", "f": 23, }],
- "RP% - Pressure ratio": [746 - 1, {"dt": "16bit_uint", "g": 100, }],
+ "PID: pressure correction": [746 - 1, {"dt": "16bit_uint", "g": 100, }],
# Format; x.xx %
"PR+ - Max pressure tolerance % (P+)": [747 - 1, {"dt": "16bit_uint", "g": 10, }],
# Format: x.x %
@@ -297,6 +297,7 @@ registers = {
# | 15 14 13 12 11 10 9 8 | 7 6 5 4 | 3 2 1 0 |
# | PSQ | | PSOUT |
# PSOUT MODE: 0 = While test run 1 = After start delay 2 = Always 3 = Only during start delay
+ "Various flags": [758 - 1, {"dt": "16bit_uint", }]
# 1001-1060 Table of the last test performed X The order of the parameters is always the same, as indicated for register from 701 to 759.
# 10001-10060 Direct access to test program table number 1 X X The order of the parameters is always the same, as indicated for register from 701 to 759.
diff --git a/src/components/test_component.py b/src/components/test_component.py
deleted file mode 100644
index 8989791..0000000
--- a/src/components/test_component.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from random import random
-
-from .component import Component
-
-
-class TestComponent(Component):
- def __init__(
- self,
- config=None,
- name=None,
- period=1,
- lazy=True,
- paused=False,
- threaded=True,
- ):
- super().__init__(
- config=config,
- name=name,
- period=period,
- lazy=lazy,
- paused=paused,
- threaded=threaded,
- )
- self.parameter = self.config[self.name]["parameter"]
-
- def _get(self, data=None):
- super()._get([self.parameter] + [random() for i in range(2)])
-
- def _set(self, val=None):
- super()._set(val)
diff --git a/src/components/usb_586x.py b/src/components/usb_586x.py
index e4d12c1..707f246 100644
--- a/src/components/usb_586x.py
+++ b/src/components/usb_586x.py
@@ -5,10 +5,11 @@ import time
from enum import Enum
from PyQt5.QtCore import QMutex, Qt, QTimer, pyqtSlot, pyqtSignal
+from PyQt5.QtWidgets import QMessageBox, QApplication
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:
@@ -38,10 +39,12 @@ class USB_586x(Component):
def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True):
super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
+ self.buffer = None
+ self.io_ok = False
self.mutex = QMutex()
self.simulate="--sim-io" in sys.argv
# DEVICE INFORMATION
- self.id=config["digital_io"]["id"]
+ self.id=config[name]["id"]
if "5860" in self.id:
self.type = "5860"
self.in_size = 1
@@ -53,15 +56,14 @@ class USB_586x(Component):
self.info = self.DeviceInformation()
self.info.Description = self.id
- # self.info.DeviceNumber = -1
self.info.DeviceMode = 1
self.info.ModuleIndex = 0
self.open_device()
# SET ALL RELAYS OFF
- for bit in range(0, self.out_size*8):
- self.set_bit(int(bit/8), bit%8, False)
+ for bit in range(0, self.out_size * 8):
+ self.set_bit(int(bit/8), bit % 8, False)
self.state_delay = 1
self.last_get = None
@@ -69,14 +71,23 @@ class USB_586x(Component):
self.last_out = None
def open_device(self):
- # DIGITAL INPUTS CLASS
+ # DIGITAL I/O CLASS
if not self.simulate:
+ self.log.info("OPENING USB MODULE...")
if is_win:
- self.di_ctrl = InstantDiCtrl(self.info.Description)
- self.do_ctrl = InstantDoCtrl(self.info.Description)
- self.di_read = self.di_ctrl.readAny
- self.do_write_bit = self.do_ctrl.writeBit
- self.buffer = ctypes.create_string_buffer(2)
+ try:
+ self.di_ctrl = InstantDiCtrl(self.info.Description)
+ self.do_ctrl = InstantDoCtrl(self.info.Description)
+ self.di_read = self.di_ctrl.readAny
+ self.do_write_bit = self.do_ctrl.writeBit
+ self.buffer = ctypes.create_string_buffer(2)
+ self.io_ok=True
+ except ValueError:
+ QMessageBox.critical(None, "ERRORE", f"ERRORE I/O DIGITALE - VERIFICARE CONNESSIONE USB")
+ exit(-1)
+ self.io_ok = False
+
+ time.sleep(1)
else:
self.di_create = libbiodaq.AdxInstantDiCtrlCreate
self.di_create.restype = ctypes.c_void_p
@@ -108,12 +119,14 @@ class USB_586x(Component):
self.do_ctrl = self.do_create()
self.di_init_status = self.di_setSelectedDevice(self.di_ctrl, ctypes.byref(self.info))
self.do_init_status = self.do_setSelectedDevice(self.do_ctrl, ctypes.byref(self.info))
+ self.io_ok = True
else:
self.di_ctrl = InstantDiCtrl(self.info.Description)
self.do_ctrl = InstantDoCtrl(self.info.Description)
self.di_read = self.di_ctrl.readAny
self.do_write_bit = self.do_ctrl.writeBit
self.buffer = ctypes.create_string_buffer(2)
+ self.io_ok = True
def close_device(self):
pass
@@ -156,25 +169,42 @@ class USB_586x(Component):
def get(self):
self.mutex.lock()
read = []
- if is_win or self.simulate:
- if self.simulate:
- 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:
- self.buffer = ret[1]
- for byte_num in range(len(self.buffer)):
- byte = self.buffer[byte_num]
- read.append([bool(byte & m) for m in self.masks])
+ retry=0
+ max_retry = 3
+ while retry < max_retry:
+
+ if is_win or self.simulate:
+ if self.simulate:
+ read=[1,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]
+ break
else:
- self.buffer = None
- else:
- self.di_read(self.di_ctrl, 0, self.in_size, self.buffer)
+ if self.io_ok:
+ ret = self.di_read(0, self.in_size)
+ if ret[0].value == ErrorCode.Success.value:
+ self.buffer = ret[1]
+ for byte_num in range(len(self.buffer)):
+ byte = self.buffer[byte_num]
+ read.append([bool(byte & m) for m in self.masks])
+ else:
+ self.buffer = None
+ self.log.error(f"READ ERROR")
+ self.di_ctrl.dispose()
+ self.do_ctrl.dispose()
+ self.io_ok = False
- for byte_num in range(len(self.buffer)):
- byte = int.from_bytes(self.buffer[byte_num], "little")
- read.append([bool(byte & m) for m in self.masks])
+
+ if self.io_ok:
+ break
+ else:
+ time.sleep(1)
+ self.open_device()
+ else:
+ self.di_read(self.di_ctrl, 0, self.in_size, self.buffer)
+
+ for byte_num in range(len(self.buffer)):
+ byte = int.from_bytes(self.buffer[byte_num], "little")
+ read.append([bool(byte & m) for m in self.masks])
self.mutex.unlock()
return read
@@ -193,13 +223,17 @@ class USB_586x(Component):
def set_bit(self, byte, bit, val):
self.mutex.lock()
# print("set", byte, bit, not val, flush=True)
- if not self.simulate:
- if is_win:
- ret=self.do_write_bit(byte, bit, int(val))
+ if self.io_ok:
+ if not self.simulate:
+ if is_win:
+ ret=self.do_write_bit(byte, bit, int(val))
+ else:
+ ret=self.do_write_bit(self.do_ctrl, byte, bit, int(val))
else:
- ret=self.do_write_bit(self.do_ctrl, byte, bit, int(val))
+ ret = ErrorCode.Success
+
else:
- ret = ErrorCode.Success
+ ret =False
self.mutex.unlock()
return ret
@@ -208,15 +242,15 @@ class USB_586x(Component):
ok = False
retry=0
max_retry = 3
- while not ok and retry = 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=['com:COM5:pn532']
+else:
+ dev_list = ['tty:USB0:pn532', 'tty:USB1:pn532', 'tty:USB2:pn532']
while True:
try:
if not connected:
- connected=clf.open('tty:USB0:pn532')
+ 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:
@@ -37,10 +78,12 @@ while True:
print("ERROR NOT NDEF")
else:
print("NO TARGET")
+ else:
+ print("NOT CONNECTED")
except Exception as e:
print(f"EXCEPTION {e}")
connected=False
- time.sleep(0.3)
+ 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..7b7d869 100644
--- a/src/ui/__init__.py
+++ b/src/ui/__init__.py
@@ -1,6 +1,10 @@
+from .widget import Widget
+from .window import Window
+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 +12,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
@@ -36,6 +39,7 @@ from .test_count import Test_Count
from .test_count_end import Test_Count_End
from .test_fail import Test_Fail
from .test_home import Test_Home
+from .test_instructions_reminder import Test_Instructions_Reminder
from .test_leak import Test_Leak
from .test_resistance import Test_Resistance
from .test_screws import Test_Screws
@@ -43,5 +47,3 @@ from .test_test import Test_Test
from .test_vision import Test_Vision
from .users_management import Users_Management
from .vision_step_editor import Vision_Step_Editor
-from .widget import Widget
-from .window import Window
diff --git a/src/ui/about/about.ui b/src/ui/about/about.ui
index 54b403b..4cec820 100644
--- a/src/ui/about/about.ui
+++ b/src/ui/about/about.ui
@@ -78,41 +78,27 @@
-
-
-
- Telefono:
-
-
-
- -
-
-
- +39 0118000876
-
-
-
- -
P.IVA:
- -
+
-
11836090016
- -
+
-
Indirizzo:
- -
+
-
Via Vittime delle Foibe, 10 10036 - Settimo Torinese (TO)
diff --git a/src/ui/barcode_recipe_selection/barcode_recipe_selection.py b/src/ui/barcode_recipe_selection/barcode_recipe_selection.py
index 4541d10..07f2b7b 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",bg_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/barcode_recipe_selection/barcode_recipe_selection.ui b/src/ui/barcode_recipe_selection/barcode_recipe_selection.ui
index 2805d48..b45d4a3 100644
--- a/src/ui/barcode_recipe_selection/barcode_recipe_selection.ui
+++ b/src/ui/barcode_recipe_selection/barcode_recipe_selection.ui
@@ -6,8 +6,8 @@
0
0
- 1445
- 793
+ 1273
+ 698
@@ -27,30 +27,6 @@
0
-
-
-
-
- 0
- 0
-
-
-
-
- 200
- 200
-
-
-
-
- 12
-
-
-
-
-
-
-
- -
@@ -70,13 +46,11 @@
- 123
-456
-abc
+
- -
+
-
diff --git a/src/ui/count_step_editor/count_step_editor.py b/src/ui/count_step_editor/count_step_editor.py
index f82bd21..509efb5 100644
--- a/src/ui/count_step_editor/count_step_editor.py
+++ b/src/ui/count_step_editor/count_step_editor.py
@@ -6,5 +6,6 @@ class Count_Step_Editor(Editor):
super().__init__(action=action, cell_widget=cell_widget)
self.spec.update({
"amount": self.amount_sb,
- "warning_img": self.warning_img_le
+ "warning_img": self.warning_img_le,
+ "require_discard_piece": self.require_discard_piece_cb
})
diff --git a/src/ui/count_step_editor/count_step_editor.ui b/src/ui/count_step_editor/count_step_editor.ui
index 4b2f5b4..d539951 100644
--- a/src/ui/count_step_editor/count_step_editor.ui
+++ b/src/ui/count_step_editor/count_step_editor.ui
@@ -6,18 +6,63 @@
0
0
- 692
- 202
+ 689
+ 375
Count Step Editor
+
-
+
+
+
+ DejaVu Sans
+ 10
+ 50
+ false
+
+
+
+ Istruzioni operative
+
+
+
-
+
+
+
+ DejaVu Sans
+ 10
+ 50
+ false
+
+
+
+
+ -
+
+
+
+ DejaVu Sans
+ 10
+ 50
+ false
+
+
+
+ Immagine warning iniziale
+
+
+
+
+
+
-
+ DejaVu Sans
10
50
false
@@ -29,6 +74,14 @@
-
+
+
+ DejaVu Sans
+ 10
+ 50
+ false
+
+
9999
@@ -36,6 +89,14 @@
-
+
+
+ DejaVu Sans
+ 10
+ 50
+ false
+
+
Quantità
@@ -44,29 +105,40 @@
- -
-
+
-
+
+ DejaVu Sans
10
50
+ false
false
- Istruzioni operative
+ Contenitore di segregazione scarti
-
-
-
-
+
+
-
+
+
+
+ DejaVu Sans
+ 10
+ 50
+ false
+ false
+
+
+
+ Qt::RightToLeft
+
- Immagine warning iniziale
+ Richiedi inserimento pezzo di scarto dentro contenitore di segregazione
- -
-
-
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/icons/edit.png b/src/ui/icons/edit.png
new file mode 100644
index 0000000..352c09d
Binary files /dev/null and b/src/ui/icons/edit.png differ
diff --git a/src/ui/icons/ko.png b/src/ui/icons/ko.png
new file mode 100755
index 0000000..363e28e
Binary files /dev/null and b/src/ui/icons/ko.png differ
diff --git a/src/ui/icons/off.png b/src/ui/icons/off.png
new file mode 100644
index 0000000..fc54081
Binary files /dev/null and b/src/ui/icons/off.png differ
diff --git a/src/ui/icons/ok.png b/src/ui/icons/ok.png
new file mode 100755
index 0000000..c1b973e
Binary files /dev/null and b/src/ui/icons/ok.png differ
diff --git a/src/ui/icons/reload.png b/src/ui/icons/reload.png
new file mode 100644
index 0000000..f9c8763
Binary files /dev/null and b/src/ui/icons/reload.png differ
diff --git a/src/ui/icons/warning.png b/src/ui/icons/warning.png
new file mode 100755
index 0000000..196568b
Binary files /dev/null and b/src/ui/icons/warning.png differ
diff --git a/src/ui/imgs/calibrated-leak-remove.png b/src/ui/imgs/calibrated-leak-remove.png
new file mode 100644
index 0000000..5bb0476
Binary files /dev/null and b/src/ui/imgs/calibrated-leak-remove.png differ
diff --git a/src/ui/imgs/calibrated-leak.png b/src/ui/imgs/calibrated-leak.png
new file mode 100644
index 0000000..413db50
Binary files /dev/null and b/src/ui/imgs/calibrated-leak.png differ
diff --git a/src/ui/imgs/neo_red.ico b/src/ui/imgs/neo_red.ico
new file mode 100644
index 0000000..82aa4f6
Binary files /dev/null and b/src/ui/imgs/neo_red.ico differ
diff --git a/src/ui/imgs/r5.png b/src/ui/imgs/r5.png
new file mode 100644
index 0000000..84d2b0b
Binary files /dev/null and b/src/ui/imgs/r5.png differ
diff --git a/src/ui/instruction_step_editor/instruction_step_editor.py b/src/ui/instruction_step_editor/instruction_step_editor.py
index ab723a9..a5511d3 100644
--- a/src/ui/instruction_step_editor/instruction_step_editor.py
+++ b/src/ui/instruction_step_editor/instruction_step_editor.py
@@ -4,8 +4,3 @@ from ui.editor import Editor
class Instruction_Step_Editor(Editor):
def __init__(self, action=None, cell_widget=None):
super().__init__(action=action, cell_widget=cell_widget)
- self.spec.update({
- "num_tape": self.tape_sb,
- "num_ring": self.ring_sb,
- "num_piece": self.piece_sb,
- })
diff --git a/src/ui/instruction_step_editor/instruction_step_editor.ui b/src/ui/instruction_step_editor/instruction_step_editor.ui
index 4f68bd8..f4a14a6 100644
--- a/src/ui/instruction_step_editor/instruction_step_editor.ui
+++ b/src/ui/instruction_step_editor/instruction_step_editor.ui
@@ -38,86 +38,7 @@
Controllo montaggio
-
- -
-
-
-
- 300
- 16777215
-
-
-
- Quantità sensori anello (SA)
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 50
- 16777215
-
-
-
-
- -
-
-
-
- 300
- 16777215
-
-
-
- Quantità sensori presenza pezzo(SP)
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 50
- 16777215
-
-
-
-
- -
-
-
-
- 300
- 16777215
-
-
-
- Quantità nastri oggettivazione (N)
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
-
- -
-
-
-
- 50
- 16777215
-
-
-
-
-
+
diff --git a/src/ui/leak_step_editor/leak_step_editor.py b/src/ui/leak_step_editor/leak_step_editor.py
index e157ef2..267c341 100644
--- a/src/ui/leak_step_editor/leak_step_editor.py
+++ b/src/ui/leak_step_editor/leak_step_editor.py
@@ -22,5 +22,7 @@ class Leak_Step_Editor(Editor):
"flush_time": self.flush_time_sb,
"flush_pressure": self.flush_pressure_sb,
# relay
- "relay_config": self.relay_config_sb
+ "chan_sel": self.chan_sel_sb,
+ "ext_blow_time": self.ext_blow_time_sb,
+ "ext_flush_time": self.ext_flush_time_sb,
})
diff --git a/src/ui/leak_step_editor/leak_step_editor.ui b/src/ui/leak_step_editor/leak_step_editor.ui
index 1bf8742..4aefc2c 100644
--- a/src/ui/leak_step_editor/leak_step_editor.ui
+++ b/src/ui/leak_step_editor/leak_step_editor.ui
@@ -6,8 +6,8 @@
0
0
- 1375
- 252
+ 1387
+ 219
@@ -285,51 +285,64 @@
- Scarico
+ Scarico(interno Tecna)
- -
-
-
- FST: Tempo scarico
-
-
-
- -
-
-
- FSL: Scarico Limite
-
-
-
- -
+
-
9999
- -
-
-
- 9999
-
-
-
- -
+
-
s
- -
+
-
mbar
+ -
+
+
+ 9999
+
+
+
+ -
+
+
+ FSL: Scarico Limite
+
+
+
+ -
+
+
+ FST: Tempo scarico
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 0s = Scarico interno disabilitato
+
+
+
@@ -343,11 +356,31 @@
- Elettrovalvole
+ Soffiaggio/scarico esterno
+ -
+
+
+ Tempo soffiaggio pre-prova
+
+
+
-
-
+
+
+
+ 50
+ 16777215
+
+
+
+ 9999
+
+
+
+ -
+
50
@@ -362,7 +395,41 @@
-
- Configurazione elettrovalvole
+ Selezione canale di prova
+
+
+
+ -
+
+
+ s
+
+
+
+ -
+
+
+
+ 50
+ 16777215
+
+
+
+ 9999
+
+
+
+ -
+
+
+ Tempo scarico esterno post-prova
+
+
+
+ -
+
+
+ s
diff --git a/src/ui/login/login.py b/src/ui/login/login.py
index 07309aa..bbc0d52 100755
--- a/src/ui/login/login.py
+++ b/src/ui/login/login.py
@@ -1,8 +1,10 @@
+import platform
+import subprocess
import sys
from lib.db import Session, Users
from PyQt5.QtCore import QTimer, pyqtSignal
-from PyQt5.QtGui import QKeySequence
+from PyQt5.QtGui import QKeySequence, QIcon
from PyQt5.QtWidgets import QMessageBox, QShortcut
from ui.widget import Widget
@@ -22,6 +24,9 @@ class Login(Widget):
QShortcut(QKeySequence("Return"), self).activated.connect(self.login_b.click)
QShortcut(QKeySequence("Enter"), self).activated.connect(self.login_b.click)
self.login_b.clicked.connect(self.try_login)
+ self.ICON_EDIT = QIcon('src/ui/icons/edit.png')
+ self.psw_edit_b.setIcon(self.ICON_EDIT)
+ self.psw_edit_b.clicked.connect(self.show_osk)
# TESTING
if "--auto-login-admin" in sys.argv:
self.user_cb.setCurrentText("ADMIN")
@@ -51,3 +56,8 @@ class Login(Widget):
login_count += 1
# /TESTING
self.successful_login.emit()
+
+ def show_osk(self):
+ self.password_le.setFocus()
+ if platform.system().lower() == 'windows':
+ subprocess.Popen(["open_osk.bat"]) # OPEN ON SCREEN KEYBOARD
diff --git a/src/ui/login/login.ui b/src/ui/login/login.ui
index 4ba00b7..2681bf1 100755
--- a/src/ui/login/login.ui
+++ b/src/ui/login/login.ui
@@ -6,8 +6,8 @@
0
0
- 1388
- 574
+ 1397
+ 658
@@ -19,33 +19,35 @@
Login
- -
-
+
-
+
+
+
+ 24
+
+
+
+ BENVENUTO, PER INIZIARE IL COLLAUDO, EFFETTUA L' ACCESSO:
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
- Qt::Horizontal
+ Qt::Vertical
- 40
- 20
+ 20
+ 40
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
+
-
Qt::Vertical
@@ -58,8 +60,14 @@
- -
+
-
+
+
+ 600
+ 16777215
+
+
ACCESSO OPERATORE
@@ -77,19 +85,6 @@
- -
-
-
-
- 300
- 300
-
-
-
- PASSWORD
-
-
-
-
@@ -103,7 +98,20 @@
- -
+
-
+
+
+
+ 300
+ 300
+
+
+
+ PASSWORD
+
+
+
+ -
ACCEDI
@@ -129,37 +137,34 @@
+ -
+
+
+
+ 41
+ 41
+
+
+
+
+ 41
+ 41
+
+
+
+
+
+
+
+ 24
+ 24
+
+
+
+
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 24
-
-
-
- BENVENUTO, PER INIZIARE IL COLLAUDO, EFFETTUA L' ACCESSO:
-
-
- Qt::AlignCenter
-
-
-
diff --git a/src/ui/main_window/main_window.ui b/src/ui/main_window/main_window.ui
index 0ec3684..5b8576c 100644
--- a/src/ui/main_window/main_window.ui
+++ b/src/ui/main_window/main_window.ui
@@ -50,7 +50,6 @@
-
@@ -120,6 +123,11 @@
Selezione ricetta da barcode
+
+
+ Ristampa etichetta
+
+
diff --git a/src/ui/recipe_selection/recipe_selection.py b/src/ui/recipe_selection/recipe_selection.py
index 06ec26b..352b656 100755
--- a/src/ui/recipe_selection/recipe_selection.py
+++ b/src/ui/recipe_selection/recipe_selection.py
@@ -34,7 +34,7 @@ class Recipe_Selection(Widget):
self.defaults = self.config.get("recipes_defaults", noner)
self.unsupported_steps = unsupported_steps
if not self.second_leak_test_enabled:
- self.unsupported_steps.add("second_leak_test")
+ self.unsupported_steps.add("leak_2")
session = Users.get_session()
if session.is_admin:
readonly = False
@@ -57,6 +57,13 @@ class Recipe_Selection(Widget):
}
filters = {"archived": False}
step_defaults = self.read_steps(self.config.get("recipes_defaults", noner), noner)
+ custom_label_folder=f"config/label_templates/{str(self.config.machine_id)}/"
+ standard_label_folder=f"config/label_templates/"
+ if os.path.exists(custom_label_folder):
+ label_folder = custom_label_folder
+ else:
+ label_folder = standard_label_folder
+
step_defaults.update({
"vision": {
# "recipe": sorted(glob("*.ini", root_dir="./config/vision/recipes/")), # only in python3.10
@@ -64,7 +71,7 @@ class Recipe_Selection(Widget):
},
"print": {
# "template": sorted(glob("*.prn", root_dir="./config/label_templates/")), # only in python3.10
- "template": sorted(map(os.path.basename, glob("./config/label_templates/*.prn"))),
+ "template": sorted(map(os.path.basename, glob(f"{label_folder}*.prn"))),
},
}),
self.crud = Crud(
@@ -129,7 +136,7 @@ class Recipe_Selection(Widget):
self.delete_all_b.setVisible(False)
# TESTING
if "--auto-select" in sys.argv:
- recipe = "000952054"
+ recipe = "R54967"
cn = self.crud.select_index["name"]
self.crud.db_tw.clearSelection()
for rn in range(1, self.crud.db_tw.rowCount()):
@@ -185,6 +192,7 @@ class Recipe_Selection(Widget):
"count": {
"amount": row.get("dimensione_lotto", defaults["dimensione_lotto"]),
"warning_img": row.get("immagine_warning", ""),
+ "require_discard_piece": row.get("richiedi_inserimento_scarto",defaults["richiedi_inserimento_scarto"])
},
"connector": {
"connector": row.get("connettore", defaults["connettore"]),
@@ -201,11 +209,7 @@ class Recipe_Selection(Widget):
"screws": {
"quantity": row.get("viti", defaults["viti"])
},
- "instruction": {
- "num_tape": int(self.get_def(row,"numero nastri (n)")),
- "num_ring": int(self.get_def(row,"numero sensori anello (sa)")),
- "num_piece": int(self.get_def(row,"numero sensori presenza (sp)"))
- },
+ "instruction": {},
"leak_1": {
"pre_filling_time": int(row.get("tempo_pre_riempimento", defaults["tempo_pre_riempimento"])),
"pre_filling_pressure": int(row.get("pressione_pre_riempimento", defaults["pressione_pre_riempimento"])),
@@ -219,7 +223,9 @@ class Recipe_Selection(Widget):
"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"]))
+ "chan_sel": int(row.get("canale_di_prova", defaults["canale_di_prova"])),
+ "ext_flush_time": int(row.get("tempo_svuotamento_esterno", defaults["tempo_svuotamento_esterno"])),
+ "ext_blow_time": int(row.get("tempo_soffiaggio_esterno", defaults["tempo_soffiaggio_esterno"])),
},
"leak_2": {
"pre_filling_time": int(row.get("tempo_pre_riempimento_2", defaults["tempo_pre_riempimento_2"])),
@@ -234,7 +240,9 @@ class Recipe_Selection(Widget):
"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"]))
+ "chan_sel": int(row.get("canale_di_prova_2", defaults["canale_di_prova_2"])),
+ "ext_flush_time": int(row.get("tempo_svuotamento_esterno_2", defaults["tempo_svuotamento_esterno"])),
+ "ext_blow_time": int(row.get("tempo_soffiaggio_esterno_2", defaults["tempo_soffiaggio_esterno"])),
},
"vision": {
"recipe": row.get("ricetta_visione", defaults["ricetta_visione"]),
diff --git a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py
index bf30dac..c34536c 100644
--- a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py
+++ b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.py
@@ -12,6 +12,7 @@ from ui.screws_step_editor import Screws_Step_Editor
from ui.vision_step_editor import Vision_Step_Editor
from ui.instruction_step_editor import Instruction_Step_Editor
+
class Recipe_Spec_And_Step_Editor(Editor):
def __init__(self, action=None, cell_widget=None, unsupported_steps=None):
super().__init__(action=action, cell_widget=cell_widget)
diff --git a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui
index e4433ed..506f39e 100644
--- a/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui
+++ b/src/ui/recipe_spec_and_step_editor/recipe_spec_and_step_editor.ui
@@ -42,7 +42,7 @@ Fasi di Test
- Lotto
+ Generale
-
diff --git a/src/ui/rfid_recipe_selection/__init__.py b/src/ui/rfid_recipe_selection/__init__.py
deleted file mode 100644
index b3a3f30..0000000
--- a/src/ui/rfid_recipe_selection/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 9b2ee0b..0000000
--- a/src/ui/rfid_recipe_selection/rfid_recipe_selection.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import sys
-
-import peewee
-from PyQt5 import Qt
-
-from lib.helpers import timing
-from PyQt5.QtCore import Qt, QTimer, QThread
-from PyQt5.QtGui import QKeySequence, QPixmap, QPalette, QColor
-from PyQt5.QtWidgets import QShortcut, QApplication
-from ui.widget import Widget
-from lib import db
-from lib.db.models import Recipes
-
-class RFID(Widget):
- def __init__(self, parent):
- super().__init__()
- self.parent=parent
- self.recipe_db_model=Recipes
- self.status_palettes = {
- True: QPalette(),
- "": QPalette(),
- "warning": QPalette(),
- False: QPalette(),
- None: QPalette(),
- }
- self.status_palettes[True].setColor(QPalette.Base, Qt.green)
- self.status_palettes[False].setColor(QPalette.Base, Qt.red)
- self.status_palettes["warning"].setColor(QPalette.Base, QColor(255, 165, 0))
- self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0))
-
- self.delay_timer = QTimer()
- self.delay_timer.setSingleShot(True)
- self.delay_timer.timeout.connect(self.reset_display)
-
- self.ok_timer = QTimer()
- self.ok_timer.setSingleShot(True)
- self.ok_timer.timeout.connect(self.set_recipe)
-
- def start(self, recipe=None, step=None, pieces=None):
-
- self.rfid_input_l.setPalette(self.status_palettes[None])
- self.rfid_input_l.setPlainText("")
-
- def get(self, data=None, override=False):
- if not len(data):
- data = None
- if data is None:
- return
- else:
- lines = data
- if lines[0]=="ERRECINQUE RFID":
- # RECIPE CODE FOUND
- self.recipe=lines[1]
- self.rfid_input_l.setPalette(self.status_palettes[True])
- self.ok_timer.start(2000)
-
- else:
- # RECIPE CODE NOT FOUND
- self.rfid_input_l.setPalette(self.status_palettes[False])
- self.instruction_text("FORMATO RFID DIMA NON VALIDO", "red")
- self.delay_timer.start(3000)
-
- # LOOKUP RECIPE
-
- def set_recipe(self):
- try:
- recipe = self.recipe_db_model.get_by_id(self.recipe)
- self.parent.set_recipe(recipe)
- except peewee.DoesNotExist:
- self.rfid_input_l.setPalette(self.status_palettes[False])
- self.instruction_text("RICETTA NON TROVATA","red")
- self.delay_timer.start(3000)
-
-
- def reset_display(self):
- self.rfid_input_l.setFocus()
- self.rfid_input_l.setPlainText("")
- self.rfid_input_l.setPalette(self.status_palettes[""])
- self.instruction_text("SCANSIONARE BARCODE SELEZIONE RICETTA")
-
- def instruction_text(self,text,color=None):
- if getattr(self.parent.centralWidget, "set_text"):
- self.parent.centralWidget.set_text(text, color=color)
-
-
diff --git a/src/ui/rfid_recipe_selection/rfid_recipe_selection.ui b/src/ui/rfid_recipe_selection/rfid_recipe_selection.ui
deleted file mode 100644
index 2805d48..0000000
--- a/src/ui/rfid_recipe_selection/rfid_recipe_selection.ui
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
- 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 bf2faf7..f1dd5c1 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
@@ -55,6 +55,7 @@ class Test(Widget):
else:
self.recipe_selection_mode = "table"
self.step = None
+ self.tester_component = "tecna_t3" if "tecna_t3" in self.components.keys() else "furness_controls"
self.unsupported_steps = set()
self.steps_dependencies = {
"count": set(),
@@ -62,8 +63,8 @@ class Test(Widget):
"instruction":{"digital_io"},
"screws": {"screwdriver", "tecna_t3", },
"resistance": {"multicomp", },
- "leak_1": {"tecna_t3", },
- "leak_2": {"tecna_t3", },
+ "leak_1": {self.tester_component, },
+ "leak_2": {self.tester_component, },
"vision": {("uvc_camera", "galaxy_camera", ), "vision", "vision_saver", }, # "neo_pixels", },
"print": {"label_printer", },
}
@@ -91,9 +92,12 @@ class Test(Widget):
"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(parent=self)),
+ "blow": Test_Assembly(img_path=None, text=u"SOFFIAGGIO TUBO IN CORSO - ATTENDERE...", widget=Test_Warning_Img(components=self.components, recipe=self.recipe, step=self.step)),
"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,parent=self)),
+ "flush": Test_Assembly(img_path=None, text=u"SCARICO ARIA IN CORSO - ATTENDERE...", widget=Test_Warning_Img(components=self.components, recipe=self.recipe, step=self.step)),
"instruction": Test_Assembly(img_path=None, text=u"ESEGUIRE LE OPERAZIONI DI MONTAGGIO INDICATE IN FIGURA", widget=Test_Instructions(components=self.components, recipe=self.recipe,bench_name=self.config.machine_id, step=self.step)),
+ "piece_removal": Test_Assembly(img_path=None, text=u"RIMUOVERE IL PEZZO APRENDO TUTTE LE CHIUSURE", 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)),
"screws": Test_Assembly(img_path=None, text=u"AVVITARE TUTE LE VITI COME INDICATO", widget=Test_Screws(components=self.components, recipe=self.recipe, step=self.step, pieces=self.pieces)),
@@ -106,16 +110,18 @@ class Test(Widget):
self.cycle_steps = None
self.cycle_index = -1
self.print_step = None
+ self.last_label = None
+ self.require_discard_piece = False
# SETUP AUTOTEST
self.autotest_request = False
self.autotesting = False
self.autotesting_reason = None
self.autotest_cycle_steps = None
if "--no-autotest" not in sys.argv:
- self.autotest_period = 8.5 * 60 * 60 * 1000 # 8.5 HOURS
+ self.autotest_period = int(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")
+ #if not self.config["autotest_done"]:
+ # self.request_autotest("init")
else:
self.autotest_period = None
# INIT TEST DATA
@@ -124,6 +130,7 @@ class Test(Widget):
# CONNECT CYCLE CONTROLS
self.cancel_b.clicked.connect(self.fail_cycle)
self.change_recipe_b.clicked.connect(self.change_recipe)
+ self.reset_count_b.clicked.connect(self.reset_count)
for step_name, w in self.cycle_available_steps.items():
if hasattr(w, "ok"):
# custom ok handlers should call next again
@@ -136,6 +143,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
@@ -182,6 +193,8 @@ class Test(Widget):
def set_recipe_mode_barcode(self):
self.recipe_selection_mode = "barcode"
self.change_recipe()
+ def reprint_label(self):
+ self.print(self.last_label, self.print_step.spec.get("template", "EtichettaR5"))
def fail_cycle(self):
self.next(action="fail")
@@ -190,41 +203,52 @@ 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.autotest_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")
def next(self, action=None):
if self.step is not None:
- self.log.debug(f"cycle next: cycle step: {model_to_dict(self.step)!r} action: {action!r}")
+ self.log.info(f"cycle step: {model_to_dict(self.step)!r} action: {action!r} current index:{self.cycle_index}")
else:
- self.log.debug(f"cycle next: cycle step: {self.step!r} action: {action!r}")
+ self.log.info(f"cycle step: {self.step!r} action: {action!r} current index:{self.cycle_index}")
current_w = self.centralWidget
if hasattr(current_w, "stop"):
current_w.stop()
if action == "change_recipe":
self.log.info(f"cycle next: action: {action!r}")
self.set_recipe(recipe=None)
+ self.cycle_available_steps["leak_1"].widget.recipe_written = False
+ self.cycle_available_steps["leak_2"].widget.recipe_written = False
self.step = Steps(type="select_recipe")
self.cycle_index = -1
+ self.recipe=None
+ self.cycle_steps=None
# 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
@@ -232,8 +256,10 @@ class Test(Widget):
if self.recipe is None or self.cycle_steps is None:
# if recipe not set: select_recipe
if self.recipe_selection_mode == "barcode":
+ self.log.info(f"returning to barcode recipe selection")
self.step = Steps(type="barcode_recipe_selection")
else:
+ self.log.info(f"returning to recipe selection table")
self.step = Steps(type="select_recipe")
elif action is None:
if self.autotest_request is not False and self.autotest_cycle_steps is not None and not self.autotesting and (self.cycle_index == -1 or self.cycle_index + 1 >= len(self.cycle_steps)):
@@ -244,6 +270,8 @@ class Test(Widget):
self.autotest_request = False
if self.autotest_period is not None: # reset periodic autotest timer
self.time_timer.start(self.autotest_period)
+ self.require_discard_piece = False
+
if self.autotesting:
if self.cycle_index + 1 < len(self.autotest_cycle_steps):
# goto next step in autotest_cycle_steps
@@ -252,6 +280,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
@@ -272,7 +308,7 @@ class Test(Widget):
"select_recipe",
"wait",
})
- self.log.info(f"cycle next: next cycle step: {model_to_dict(self.step)!r}")
+ self.log.info(f"next cycle step: {model_to_dict(self.step)!r}")
# INIT TEST DATA IF STARTING CYCLE LOOP OR IF RESET IS NEEDED
if self.cycle_index == 0:
self.data = {"ok": True, "overridden": False}
@@ -281,6 +317,8 @@ class Test(Widget):
self.data["recipe"] = model_to_dict(self.recipe)
w = self.cycle_available_steps[self.step.type]
show = None
+ if self.step.type=="leak_2":
+ self.setCentralWidget(w) # NEED TO PRESHOW UI
if hasattr(w, "start"):
show = w.start(recipe=self.recipe, step=self.step, pieces=self.pieces)
if show is not False and w is not current_w:
@@ -289,19 +327,30 @@ class Test(Widget):
self.next_timer.start(0)
if self.step.type == "done":
self.archived = self.done()
- self.next_timer.start(2000)
+ self.last_label=copy.deepcopy(self.archived)
+ self.next_timer.start(500)
elif self.step.type == "print":
compiled_label = self.print(self.archived, self.step.spec.get("template", "EtichettaR5"))
self.archived.label = compiled_label
self.archived.save()
- self.next_timer.start(2000)
+ self.next_timer.start(500)
elif self.step.type == "wait":
- self.next_timer.start(2000)
- # UPDATE PIECES DISPLAY
+ self.next_timer.start(500)
+ # UPDATE COUNT DISPLAY
+ self.update_count_display()
+
+ def reset_count(self):
+ # COUNT RESET
+ self.pieces["ok"] = 0
+ self.pieces["ko"] = 0
+ self.update_count_display()
+
+ def update_count_display(self):
self.pieces_count_l.setText(f"{self.pieces['ok']} OK / {self.pieces['ko']} NOK / {sum(self.pieces.values())} TOT")
def set_recipe(self, recipe=None):
self.recipe = recipe
+ self.require_discard_piece = False
if self.recipe is None:
self.cycle_steps = None
self.autotest_cycle_steps = None
@@ -324,11 +373,12 @@ class Test(Widget):
skip.add(i + 1)
if "assembly" in step.spec:
if step.spec["assembly"]:
- steps.insert(i, Steps(type="instructions", spec={"num_tape": step.spec["num_tape"],
- "num_piece": step.spec["num_piece"],
- "num_ring": step.spec["num_ring"]}))
+ steps.insert(i, Steps(type="instructions", spec={}))
skip.add(i + 1)
- if step.type == "resistance":
+ if "require_discard_piece" in step.spec:
+ if step.spec["require_discard_piece"]:
+ self.require_discard_piece = True
+ if step.type == "resistance": # ADD STEP TO ENSURE REMOVAL OF CONNECTOR
steps.insert(i + 1, Steps(type="resistance", spec={
"scale": 500,
"expected": float("+inf"),
@@ -337,12 +387,18 @@ class Test(Widget):
}))
skip.add(i + 1)
if step.type == "print":
+ if print_found:
+ continue
steps.insert(i, Steps(type="done"))
print_found = True
- self.print_step=step
- skip.add(i + 1)
+ self.print_step = step
+ if self.config["hardware_config"].get("enforce_piece_removal", "no") == "yes":
+ steps.append(Steps(type="piece_removal"))
if count_found:
- steps.insert(i + 2, Steps(type="count_end"))
+ steps.append(Steps(type="count_end"))
+ if step.type in ("leak_1","leak_2"):
+ self.leak_step = step
+
if not print_found:
steps.append(Steps(type="done"))
if count_found:
@@ -405,12 +461,13 @@ class Test(Widget):
w.reset()
# UPDATE RECIPE DISPLAY
if self.recipe is not None:
- self.log.info(f"cycle recipe: cycle recipe: {model_to_dict(self.recipe)!r} cycle steps: {[model_to_dict(s) for s in self.cycle_steps]}")
+ self.log.info(f"set recipe: {model_to_dict(self.recipe)!r} cycle steps: {[model_to_dict(s) for s in self.cycle_steps]}")
self.recipe_l.setText(self.recipe.name)
self.recipe_l.setStyleSheet("")
+ self.cycle_index = -1
self.next()
else:
- self.log.info(f"cycle recipe: cycle recipe: {self.recipe!r} cycle steps: {self.cycle_steps}")
+ self.log.info(f"set recipe: {self.recipe!r} cycle steps: {self.cycle_steps}")
self.recipe_l.setText("NON SELEZIONATA")
self.recipe_l.setStyleSheet("QLabel { color: red; }")
@@ -472,17 +529,19 @@ class Test(Widget):
def done(self, ok=True):
self.log.info("cycle done, saving data...")
- #remove useless info
+ # 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"]
+ results={k:self.data[leak]["results"][self.tester_component][k] for k in ["Running test: result"]}
+
+ results.update({k:round(float(self.data[leak]["results"][self.tester_component][k]),2) for k in ["Running test: filling pressure",
+ "Running test: measured leak",
+ "Running test: pressure at the end of settling"]}
+ )
+ self.data[leak]["results"]=results
- }
if "vision" in self.data:
vision_test_1 = self.data.get("vision", {}).get("0", {})
out_paths = self.components["vision_saver"].save(
@@ -513,7 +572,7 @@ class Test(Widget):
else:
if self.autotesting_reason == "logout":
if ok:
- self.main_window.show_login()
+ self.main_window.open_login()
return archived
@@ -529,10 +588,14 @@ class Test(Widget):
def print(self, archived, label):
self.log.info("cycle print")
+ if archived is None:
+ self.log.error("attempting to print empty label")
+ return None
+
if archived.label is not None:
- raise AssertionError("this should never happen")
- self.components["label_printer"].print_label(archived.label, context=None)
- self.log.info("cycle printed already compiled label")
+ # raise AssertionError("this should never happen")
+ self.log.info("printing already compiled label")
+
# LABEL PRINT
recipe = archived.test_data.get("recipe", {})
leak_test_1 = archived.test_data.get("leak_1", {})
@@ -548,8 +611,8 @@ class Test(Widget):
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
+ leak_test_1_results["Running test: pressure at the end of measure"] = leak_test_1_results["Running test: pressure at the end of settling"] - leak_test_1_results["Running test: measured leak"]
+ printer_fields = self.print_step.spec
context = {
# RECIPE DATA
"RECIPE": self.labellify(recipe.get("name", "-")),
@@ -587,6 +650,8 @@ class Test(Widget):
"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", "-")),
+ "RESPEND": self.labellify(leak_test_1_results.get("Running test: pressure at the end of measure", "-")),
+ "RESPEND2": self.labellify(leak_test_1_results.get("Running test: pressure at the end of measure", "-")),
"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", "-")),
@@ -607,6 +672,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),
@@ -626,13 +692,6 @@ class Test(Widget):
# PRINT MAIN PRODUCT LABEL
compiled_label = self.components["label_printer"].print_label(label, context=context)
- # if recipe.get("part_number", "-") == "5802814210 R.3":
- # num_labels=2
- # else:
- # num_labels=1
- #
- # for i in range(num_labels):
- # compiled_label = self.components["label_printer"].print_label(label, context=context)
self.log.info(f"Main label printed: {context!r}")
return compiled_label
@@ -644,3 +703,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
+ self.fail_cycle()
+ self.change_recipe()
+ else:
+ if data is not None:
+ self.set_recipe_mode_barcode()
diff --git a/src/ui/test/test.ui b/src/ui/test/test.ui
index ac9e4b9..326e7f4 100755
--- a/src/ui/test/test.ui
+++ b/src/ui/test/test.ui
@@ -7,7 +7,7 @@
0
0
1252
- 146
+ 125
@@ -52,8 +52,121 @@
3
- -
-
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ OPERATORE:
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ -
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 12
+ 75
+ true
+
+
+
+ N. DISEGNO:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 40
+
+
+
+
+ 12
+ 75
+ true
+
+
+
+ CAMBIA DISEGNO
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ PROSSIMO AUTOTEST:
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
Qt::Horizontal
@@ -91,54 +204,7 @@
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 16
- 75
- true
-
-
-
- -
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- 12345
-
-
- Qt::AlignCenter
-
-
-
- -
+
-
@@ -148,7 +214,7 @@
- 120
+ 150
0
@@ -170,8 +236,8 @@
- -
-
+
-
+
12
@@ -180,11 +246,61 @@
- OPERATORE:
+ 12345
+
+
+ Qt::AlignCenter
- -
+
-
+
+
+
+ 16
+ 75
+ true
+
+
+
+ -
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ -
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
@@ -202,27 +318,20 @@
- -
-
-
-
- 0
- 0
-
+
-
+
+
+ Qt::Horizontal
-
-
- 12
- 75
- true
-
+
+
+ 40
+ 20
+
-
- N. DISEGNO:
-
-
+
- -
+
-
@@ -239,81 +348,6 @@
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 20
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 12
- 75
- true
-
-
-
- -
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 200
- 40
-
-
-
-
- 12
- 75
- true
-
-
-
- CAMBIA DISEGNO
-
-
-
-
@@ -331,8 +365,8 @@
- -
-
+
-
+
12
@@ -341,13 +375,29 @@
- DD/MM/YY HH:MM
+ -
Qt::AlignCenter
+ -
+
+
+
+ DejaVu Sans
+ 11
+ 75
+ true
+
+
+
+ AZZERA
+CONTATORE
+
+
+
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_assembly/test_assembly.ui b/src/ui/test_assembly/test_assembly.ui
index 20f4c1e..60830cf 100755
--- a/src/ui/test_assembly/test_assembly.ui
+++ b/src/ui/test_assembly/test_assembly.ui
@@ -6,8 +6,8 @@
0
0
- 94
- 130
+ 663
+ 496
@@ -26,25 +26,6 @@
0
- -
-
-
-
- 0
- 0
-
-
-
-
-
-
- false
-
-
- Qt::AlignCenter
-
-
-
-
@@ -97,6 +78,31 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 100
+ 100
+
+
+
+
+
+
+ false
+
+
+ Qt::AlignCenter
+
+
+
diff --git a/src/ui/test_fail/test_fail.py b/src/ui/test_fail/test_fail.py
index ffcc5d2..c0adc25 100644
--- a/src/ui/test_fail/test_fail.py
+++ b/src/ui/test_fail/test_fail.py
@@ -10,8 +10,8 @@ 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,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)
+ 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()
@@ -22,11 +22,12 @@ class Test_Fail(Test_Test):
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)
+ if self.parent.require_discard_piece:
+ 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",text_color="black",bg_color="red")
+ self.io_connection=self.components["digital_io"].out.connect(self.wait_discard)
self.visualize()
# TESTING
@@ -39,7 +40,8 @@ class Test_Fail(Test_Test):
def stop(self):
if "discard_box" in self.parent.config["hardware_config"].keys():
- self.disconnect(self.io_connection)
+ if hasattr(self,"io_connection"):
+ self.disconnect(self.io_connection)
super().stop()
def wait_discard(self,data=None):
@@ -50,6 +52,6 @@ class Test_Fail(Test_Test):
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]:
+ if not data[0]["digital_io"][byte_idx][bit_idx]:
self.ok.emit(None)
diff --git a/src/ui/test_instructions/test_instructions.py b/src/ui/test_instructions/test_instructions.py
index 0c18da5..dc96d3a 100644
--- a/src/ui/test_instructions/test_instructions.py
+++ b/src/ui/test_instructions/test_instructions.py
@@ -29,6 +29,7 @@ class Test_Instructions(Test_Test):
self.svg_path=os.path.join("config","instruction_images",self.bench_name,"")
self.timer = QTimer()
self.timer.timeout.connect(self.toggle_icons)
+ self.expected_input_state=True
def start(self, recipe=None, step=None, pieces=None):
show = super().start(recipe=recipe, step=step)
@@ -44,6 +45,7 @@ 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.expected_input_state = True if step.type == "instruction" else False
self.monitored_ids=self.svg_root.xpath(f'''.//*[starts-with(@id, 'sensor_')]''')
@@ -99,7 +101,9 @@ class Test_Instructions(Test_Test):
QApplication.processEvents()
def get(self, data=None, override=False):
-
+ if self.parent_assembly_widget().parent().step.type == "select_recipe":
+ self.stop()
+ return
if self.done: # avoid proccessing if completed
return
if data is None:
@@ -114,18 +118,23 @@ class Test_Instructions(Test_Test):
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]:
+ if data[0]["digital_io"][byte_idx][bit_idx] == self.expected_input_state:
self.inputs[sensor_index] = True
else:
self.inputs[sensor_index] = False
ok = False
if ok:
+ self.stop()
super().get([{
"time": timing(),
"results": {
"ok": ok,
},
}], override=override, fail=ok is False, skip_delay=False)
+ self.set_done()
+
+ self.toggle_icons()
+
def set_done(self):
self.done=True
@@ -136,6 +145,7 @@ class Test_Instructions(Test_Test):
#self.done=True
#self.done_ok = True
self.timer.stop()
+ self.disconnect(self.get_connection)
super().stop()
def reset(self):
diff --git a/src/ui/test_instructions_reminder/__init__.py b/src/ui/test_instructions_reminder/__init__.py
new file mode 100644
index 0000000..1eb8b6b
--- /dev/null
+++ b/src/ui/test_instructions_reminder/__init__.py
@@ -0,0 +1 @@
+from .test_instructions_reminder import Test_Instructions_Reminder
diff --git a/src/ui/test_instructions_reminder/test_instructions_reminder.py b/src/ui/test_instructions_reminder/test_instructions_reminder.py
new file mode 100644
index 0000000..2e6153e
--- /dev/null
+++ b/src/ui/test_instructions_reminder/test_instructions_reminder.py
@@ -0,0 +1,78 @@
+import os.path
+import sys
+import weakref
+
+from PyQt5 import QtSvg
+from PyQt5.QtCore import Qt
+
+from lib.helpers import timing
+from PyQt5.QtCore import QTimer
+from PyQt5.QtGui import QKeySequence, QPixmap
+from PyQt5.QtWidgets import QShortcut, QApplication, QVBoxLayout
+
+from lxml import etree
+
+from ui import Widget
+
+
+class Test_Instructions_Reminder(Widget):
+ def __init__(self, recipe=None, bench_name="generic"):
+ super().__init__()
+ self.bench_name = bench_name
+ self.recipe=recipe
+ 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)
+ self.svg_w.setLayout(self.layout)
+ self.svg_path=os.path.join("config","instruction_images",self.bench_name,"")
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.toggle_icons)
+
+ self.start()
+
+ def start(self, recipe=None, step=None, pieces=None):
+
+ svg_path=f"{self.svg_path}{self.recipe}.svg"
+ if not os.path.exists(svg_path):
+ svg_path=f"{self.svg_path}DEFAULT.svg"
+ 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.timer.start(1000)
+ def toggle_icons(self):
+ self.flag = not self.flag
+
+ for elem in self.tape_ids:
+ if self.flag:
+ self.show_tape(elem)
+ else:
+ self.hide_tape(elem)
+
+
+ self.show_svg()
+
+
+ def show_icon(self,id):
+ id.set("display", "inline")
+
+ def hide_icon(self,id):
+ id.set("display", "none")
+
+ def show_tape(self,id):
+ 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):
+ id.set("display", "none")
+
+ def show_svg(self):
+ self.svg_str = etree.tostring(self.svg_root)
+ self.svg_widget.load(self.svg_str)
+ QApplication.processEvents()
diff --git a/src/ui/test_instructions_reminder/test_instructions_reminder.ui b/src/ui/test_instructions_reminder/test_instructions_reminder.ui
new file mode 100644
index 0000000..7de90ab
--- /dev/null
+++ b/src/ui/test_instructions_reminder/test_instructions_reminder.ui
@@ -0,0 +1,74 @@
+
+
+ Test_Warning_Img
+
+
+
+ 0
+ 0
+ 1224
+ 922
+
+
+
+ Test Count End
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 20
+ 75
+ true
+
+
+
+ Istruzione operativa
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+
-
+
+
+
+ 1200
+ 700
+
+
+
+
+ 1200
+ 700
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/test_leak/test_leak.py b/src/ui/test_leak/test_leak.py
index 70d4669..0ea02f3 100644
--- a/src/ui/test_leak/test_leak.py
+++ b/src/ui/test_leak/test_leak.py
@@ -2,37 +2,87 @@ import sys
import time
import weakref
-from PyQt5.QtWidgets import QMessageBox, QDialog
-
+from PyQt5.QtGui import QPixmap
+from PyQt5.QtWidgets import QMessageBox, QDialog, QApplication
+from PyQt5.QtCore import Qt
from ui import Dialog
+from ui.test_instructions_reminder import Test_Instructions_Reminder
from ui.test_test import Test_Test
-from components.Automation.BDaq import ErrorCode
+
+VALVE_TIME=0.5
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.get_connection = None
+ self.io_ok = True
+ self.blow_on = False
self.parent=parent
self.step=step
+ self.recipe_written = False
self.start_b.clicked.connect(self.start_test)
- self.stop_b.clicked.connect(lambda checked, self=weakref.ref(self): self().components["tecna_t3"].stop_test())
+ self.stop_b.clicked.connect(self.stop_test)
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.setCentralWidget(Test_Instructions_Reminder(recipe=self.parent.recipe,bench_name=self.parent.config.machine_id))
dialog.show()
+ def reset(self):
+ self.components[self.tester_component].stop_test()
+ super().reset()
+
+ def stop_test(self):
+ self.components[self.tester_component].stop_test()
+ self.display_text(text="PROVA INTERROTTA", bg_color="yellow")
+ time.sleep(1)
+ self.start_b.setEnabled(True)
+ self.stop_b.setEnabled(False)
+
def start_test(self):
# print extra labels
if self.step.type == "leak_1":
self.parent.print_extra_labels()
- self.components["tecna_t3"].start_test()
+ # SELECT TEST CHANNEL
+ if self.parent.config["hardware_config"].get("external_flush_blow", None) == "present":
+ if self.parent.config["hardware_config"].get("dual_channel", None) == "present":
+ chan_sel = self.step.spec["chan_sel"] # 0=CH1, 1=CH2
+ self.set_digital_out("out_channel_select", chan_sel)
+ self.set_digital_out("in_channel_select", chan_sel)
+ time.sleep(VALVE_TIME)
+
+ # SET LED INDICATORS
+ if chan_sel == 0:
+ self.set_digital_out("ch1_led", True)
+ else:
+ self.set_digital_out("ch2_led", True)
+
+ self.blow_on=True
+ self.display_text("SOFFIAGGIO IN CORSO...")
+ self.set_digital_out("blow_led",True)
+ self.set_digital_out("blow_on",True)
+ self.set_digital_out("flush_on", True)
+ blow_time=int(self.step.spec.get('ext_blow_time',3))
+ self.set_digital_out("blow_led", True)
+ time.sleep(blow_time)
+ self.set_digital_out("blow_led", False)
+ self.set_digital_out("blow_on", False)
+ self.set_digital_out("flush_on", False)
+
+ if self.parent.config["hardware_config"].get("dual_channel", None) != "present":
+ self.set_digital_out("ch1_led", True)
+
+ self.blow_on = False
+ if not self.simulate:
+ self.components[self.tester_component].start_test()
+
def start(self, recipe=None, step=None, pieces=None):
# TESTING
- if "--test-leak" in sys.argv or "--test" in sys.argv:
+ if "--test-leak" in sys.argv:
self.simulate = True
else:
self.simulate = False
@@ -52,48 +102,59 @@ class Test_Leak(Test_Test):
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)
- self.components["tecna_t3"].resume()
+ self.fill_time_l.setText(f"{self.step.spec['filling_time']}")
+ self.settle_time_l.setText(f"{self.step.spec['settling_time']}")
+ self.meas_time_l.setText(f"{self.step.spec['test_time']}")
+
+ # SETUP TEST LOOP
+ if self.step.spec.get("autotest", False): # IF AUTOTESTING UPLOAD RECIPE EVERY TIME
+ self.recipe_written = False
+
+ if self.parent.config["hardware_config"].get("second_leak_test", "absent") == "present": # IF SECOND LEAK TEST ENABLED UPLOAD RECIPE EVERY TIME
+ self.recipe_written = False
+
+ if not self.recipe_written:
+ self.components[self.tester_component].write_recipe(self.recipe, self.step)
+ self.recipe_written=True
+
+ self.get_connection = self.components[self.tester_component].out.connect(self.get)
+ self.components[self.tester_component].resume()
if self.parent_assembly_widget is not None:
- self.parent_assembly_widget().set_text(text="WAIT")
+ self.display_text(text="ATTENDERE")
self.start_b.setEnabled(False)
self.stop_b.setEnabled(False)
- # SETUP RELAY CONFIGURATION
- if "digital_io" in self.components.keys():
- if "relay_config" in step.spec.keys():
- relay_config = step.spec["relay_config"]
- bits = [0, 0]
- if relay_config == 0:
- bits = [0,0]
- if relay_config == 1:
- bits = [0,1]
- if relay_config == 2:
- bits = [1,0]
+ if self.step.spec.get("autotest", False) == "ok_check":
+ self.display_text(text="AUTOTEST: RIMUOVERE FUGA CALIBRATA E PREMERE START PER INIZIARE LA PROVA TENUTA",
+ bg_color="blue", text_color="white")
+ super().visualize(None, img=self.status_imgs_full["calibrated-leak-remove"])
+ elif self.step.spec.get("autotest", False) == "ko_check":
+ self.display_text(
+ text="AUTOTEST: COLLEGARE TUBO-TUBO + FUGA CALIBRATA E PREMERE START PER INIZIARE LA PROVA TENUTA DI PROVA",
+ bg_color="blue", text_color="white")
+ super().visualize(None, img=self.status_imgs_full["calibrated-leak"])
+ else:
+ self.display_text(text="COLLEGARE GLI ATTACCHI PNEUMATICI E PREMERE START PER INIZIARE LA PROVA TENUTA")
- ret=self.components["digital_io"].set_bit_verify(0, 0, bits[1])
- ret=self.components["digital_io"].set_bit_verify(0, 1, bits[0])
+ if self.simulate:
+ QApplication.processEvents()
+ time.sleep(2)
+
+ # AUTO START SECOND TEST
+ if step.type == "leak_2":
+ self.recipe_written = False
+ time.sleep(1)
+ self.start_b.setEnabled(True)
+ self.start_b.click()
- if ret:
- time.sleep(1)
- # AUTO START SECOND TEST
- if step.type == "leak_2":
- self.start_b.setEnabled(True)
- self.start_b.click()
- else:
- QMessageBox.critical(None, "Errore", f"Errore di pilotaggio elettrovalvole")
return show
def stop(self):
# disable test loop
- self.components["tecna_t3"].stop_test()
- self.components["tecna_t3"].pause()
+ self.components[self.tester_component].stop_test()
+ self.components[self.tester_component].pause()
self.disconnect(self.get_connection)
super().stop()
- if self.parent_assembly_widget is not None:
- self.parent_assembly_widget().set_text(text="WAIT")
self.start_b.setEnabled(False)
self.stop_b.setEnabled(False)
@@ -107,30 +168,62 @@ class Test_Leak(Test_Test):
# TESTING
if self.simulate:
- if self.step.spec.get("autotest", False) is not True:
- data["tecna_t3"] = {
+ if "--fail-leak" in sys.argv:
+ data[self.tester_component] = {
+ "Running test: active phase": "WAITING START",
+ "Running test: result": "-----TESTING----- fail",
+ "Running test: filling pressure":"5000",
+ "Running test: measured leak":"50",
+ "Running test: pressure at the end of settling":"4999",
+ }
+ else:
+ data[self.tester_component] = {
+ "Running test: active phase": "WAITING START",
"Running test: result": "-----TESTING----- passed",
- }
- else:
- data["tecna_t3"] = {
- "Running test: result": "-----TESTING----- failed",
+ "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 "Running test: result" in data[self.tester_component]:
+ # TEST ENDED, CHECK RESULT
+ result = data[self.tester_component]["Running test: result"]
step=self.step.spec.get("autotest", "")
- if step == "ok_check":
+ 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
+ self.recipe_written=False
+ elif step == "ko_check":
+ if self.tester_component == "tecna_t3":
+ # AUTOTEST - CALIBRATED LEAK - WINDOWED TYPE, OK EXPECTED (TECNA)
+ ok = type(result) is str and "passed" in result.lower()
+ else:
+ # AUTOTEST - CALIBRATED LEAK - NON WINDOWED TYPE, FAIL EXPECTED (FURNESS CONTROLS)
+ ok = type(result) is str and "fail" in result.lower()
+ self.recipe_written = False
else:
- ok = type(result) is str and "passed" in result.lower() # NORMAL TEST
+ ok = type(result) is str and "passed" in result.lower() # NORMAL TEST, OK EXPECTED
- if "digital_io" in self.components.keys():
- # RESET RELAYS
- ret = self.components["digital_io"].set_bit_verify(0, 0, 0)
- ret = self.components["digital_io"].set_bit_verify(0, 1, 0)
+ # SET DIGITAL OUTPUTS
+ if self.parent.config["hardware_config"].get("external_flush_blow", None) == "present":
+ self.blow_on = True
+ if self.parent.config["hardware_config"].get("dual_channel", None) != "present":
+ self.set_digital_out("ch1_led", False)
+
+ self.display_text("SCARICO ESTERNO IN CORSO...")
+ self.set_digital_out("flush_led", True)
+ self.set_digital_out("flush_on", True)
+ time.sleep(VALVE_TIME)
+ flush_time = int(self.step.spec.get('ext_flush_time',3))
+ time.sleep(flush_time)
+ self.set_digital_out("flush_led", False)
+ #self.set_digital_out("flush_on", False)
+
+ if self.parent.config["hardware_config"].get("dual_channel", None) == "present":
+ self.set_digital_out("out_channel_select", False)
+ self.set_digital_out("in_channel_select", False)
+ self.set_digital_out("ch1_led", False)
+ self.set_digital_out("ch2_led", False)
else:
#result = None
ok = None
@@ -143,14 +236,14 @@ class Test_Leak(Test_Test):
#"results": {
#"ok": ok,
#"result": result,
- #"data": data["tecna_t3"],
+ #"data": data[self.tester_component],
#},
}], override=override, fail=ok is False)
def visualize(self, data=None):
if data is None:
data = {}
- d = data.get("results", {}).get("tecna_t3", {})
+ d = data.get("results", {}).get(self.tester_component, {})
for k, l in {
"Running test: active phase": self.test_phase_l,
"Real time test pressure output": self.circuit_pressure_l,
@@ -170,33 +263,43 @@ class Test_Leak(Test_Test):
"ATTESA START",
"END TEST, WAITING THE START OF A NEW TEST"
"FINE TEST",
+ "STANDBY",
+ "PRESSIONE BASSA",
+ "PRESSIONE ALTA",
+ "ERRORE"
}:
- if self.step.spec.get("autotest", False) == "ok_check":
- if self.parent_assembly_widget is not None:
- self.parent_assembly_widget().set_text(text="AUTOTEST: RIMUOVERE FUGA CALIBRATA E PREMERE START PER INIZIARE LA PROVA TENUTA",color="blue")
- 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",color="blue")
- else:
- if self.parent_assembly_widget is not None:
- self.parent_assembly_widget().set_text(text="COLLEGARE GLI ATTACCHI PNEUMATICI E PREMERE START PER INIZIARE LA PROVA TENUTA")
+
self.start_b.setEnabled(True)
self.start_b.setDefault(True)
self.start_b.setFocus()
self.stop_b.setEnabled(False)
else:
- if self.step is not None:
+ if self.step is not None and not self.blow_on:
if self.step.spec.get("autotest", False) is not True:
- if self.parent_assembly_widget is not None:
- self.parent_assembly_widget().set_text(text="PROVA TENUTA IN CORSO")
+ self.display_text(text="PROVA TENUTA IN CORSO")
else:
- if self.parent_assembly_widget is not None:
- self.parent_assembly_widget().set_text(text="AUTOTEST: PROVA TENUTA IN CORSO")
+ self.display_text(text="AUTOTEST: PROVA TENUTA IN CORSO")
self.start_b.setEnabled(False)
self.stop_b.setEnabled(True)
- ok = data.get("results", {}).get("ok", None)
- super().visualize(data, img=self.status_imgs_full[ok])
+ ok = data.get("results", {}).get("ok", None)
+
+ super().visualize(data, img=self.status_imgs_full[ok])
+
+ def display_text(self,text="", bg_color=None,text_color=None):
+ if self.parent_assembly_widget is not None:
+ self.parent_assembly_widget().set_text(text=text, bg_color=bg_color,text_color=text_color)
+ QApplication.processEvents()
+ time.sleep(0.3)
+ QApplication.processEvents()
+
+ def set_digital_out(self,out_name=None,state=1,component_name="digital_io_flush_blow"):
+ if self.io_ok:
+ bit = int(self.parent.config[component_name][out_name])
+ ret = self.components[component_name].set_bit_verify(0,bit,state)
+ if not ret:
+ QMessageBox.critical(None, "ERRORE", f"ERRORE I/O DIGITALE - VERIFICARE CONNESSIONE USB")
+ self.io_ok = False
def save_last(self):
if self.last is None:
diff --git a/src/ui/test_leak/test_leak.ui b/src/ui/test_leak/test_leak.ui
index a9844d9..a40af41 100644
--- a/src/ui/test_leak/test_leak.ui
+++ b/src/ui/test_leak/test_leak.ui
@@ -974,60 +974,6 @@
- -
-
-
-
- 0
- 0
-
-
-
-
- 12
- 75
- true
-
-
-
- Risultato
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- %v / %m
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 32
- 32
-
-
-
- -
-
-
-
-
-
-
-
@@ -1534,6 +1480,60 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Risultato
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ %v / %m
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 32
+ 32
+
+
+
+ -
+
+
+
+
+
+
-
@@ -1547,90 +1547,6 @@
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
-
-
-
-
@@ -1656,8 +1572,8 @@ border: 1px solid black;
- -
-
+
-
+
16
@@ -1666,15 +1582,12 @@ border: 1px solid black;
- Tipo di test
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+ mbar
- -
-
+
-
+
130
@@ -1698,7 +1611,257 @@ border: 1px solid black;
- -
+
-
+
+
+
+ 130
+ 16777215
+
+
+
+
+ 20
+ 50
+ false
+
+
+
+ background-color: rgb(255, 255, 255);
+border: 1px solid black;
+
+
+
+ -
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ s
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ Tempo di assestamento
+
+
+
+ -
+
+
+
+ 130
+ 16777215
+
+
+
+
+ 20
+ 50
+ false
+
+
+
+ background-color: rgb(255, 255, 255);
+border: 1px solid black;
+
+
+
+ -
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 130
+ 16777215
+
+
+
+
+ 20
+ 50
+ false
+
+
+
+ background-color: rgb(255, 255, 255);
+border: 1px solid black;
+
+
+
+ -
+
+
+
+ -
+
+
+
+ 20
+ 50
+ false
+
+
+
+ background-color: rgb(255, 255, 255);
+border: 1px solid black;
+
+
+
+ -
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ mbar
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ 0
+
+
+ NUMERO TEST
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ mbar
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 400
+ 400
+
+
+
+ -
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ Caduta minima ammessa
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 130
+ 16777215
+
+
+
+
+ 20
+ 50
+ false
+
+
+
+ background-color: rgb(255, 255, 255);
+border: 1px solid black;
+
+
+
+ -
+
+
+
+ -
@@ -1738,24 +1901,8 @@ border: 1px solid black;
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Minimum
-
-
-
- 40
- 20
-
-
-
-
- -
-
+
-
+
16
@@ -1764,12 +1911,15 @@ border: 1px solid black;
- mbar
+ Pressione di test da ricetta
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- -
-
+
-
+
16
@@ -1777,13 +1927,42 @@ border: 1px solid black;
false
-
- background-color: rgb(255, 255, 255);
-border: 1px solid black;
-
+
+ Fase di test
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
- -
+ s
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ Tempo di riempimento
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
@@ -1804,8 +1983,56 @@ border: 1px solid black;
- -
-
+
-
+
+
+
+ 16
+ 50
+ false
+
+
+
+ s
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ Tempo di prova
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ Caduta di pressione misurata
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
130
@@ -1829,8 +2056,8 @@ border: 1px solid black;
- -
-
+
-
+
16
@@ -1843,8 +2070,8 @@ border: 1px solid black;
- -
-
+
-
+
16
@@ -1853,46 +2080,24 @@ border: 1px solid black;
- mbar
-
-
-
- -
-
-
-
- 16
- 50
- false
-
-
-
- mbar
-
-
-
- -
-
-
-
- 16
- 50
- false
-
-
-
- Fase del test
+ Caduta massima ammessa
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- -
-
+
-
+
+
+
+ 130
+ 16777215
+
+
- 16
+ 20
50
false
@@ -1932,84 +2137,8 @@ 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
@@ -2022,14 +2151,22 @@ border: 1px solid black;
- -
-
-
-
- 130
- 16777215
-
+
-
+
+
+
+ 16
+ 50
+ false
+
+
+ mbar
+
+
+
+ -
+
20
@@ -2047,8 +2184,27 @@ border: 1px solid black;
- -
-
+
-
+
+
+
+ 20
+ 50
+ false
+
+
+
+ background-color: rgb(255, 255, 255);
+border: 1px solid black;
+
+
+
+ -
+
+
+
+ -
+
16
@@ -2056,30 +2212,45 @@ border: 1px solid black;
false
-
- 0
-
- NUMERO TEST
+ Pressione regolatore
- Qt::AlignCenter
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- -
-
-
-
- 0
- 0
-
+
-
+
+
+
+ 16
+ 50
+ false
+
- -
+ Tipo di test
- Qt::AlignCenter
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+ 16
+ 50
+ false
+
+
+
+ Indice di sequenza del test
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
diff --git a/src/ui/test_test/test_test.py b/src/ui/test_test/test_test.py
index d14f358..64f749d 100644
--- a/src/ui/test_test/test_test.py
+++ b/src/ui/test_test/test_test.py
@@ -18,6 +18,9 @@ class Test_Test(Widget):
def __init__(self, components=None, recipe=None, step=None, pieces=None, run_once=False, reset_on_start=True, enable_override=True):
super().__init__()
self.components = components
+ if components is not None:
+ self.tester_component="tecna_t3" if "tecna_t3" in self.components.keys() else "furness_controls"
+
self.recipe = recipe
self.step = step
self.pieces = pieces
@@ -45,13 +48,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
@@ -60,6 +63,8 @@ class Test_Test(Widget):
"": QPixmap("src/ui/imgs/neo.ico"),
"warning": QPixmap("src/ui/imgs/warning.png"),
"wait": QPixmap("src/ui/imgs/wait.png"),
+ "calibrated-leak": QPixmap("src/ui/imgs/calibrated-leak.png"),
+ "calibrated-leak-remove": QPixmap("src/ui/imgs/calibrated-leak-remove.png"),
False: QPixmap("src/ui/imgs/fail.png"),
None: QPixmap("src/ui/imgs/wait.png"),
}
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):