commit 1b565ebb076b79d99dbd93a069456988d73373e8 Author: Tyrel Souza Date: Mon Mar 14 11:31:56 2016 -0400 t push -u origin master diff --git a/.hg/00changelog.i b/.hg/00changelog.i new file mode 100644 index 0000000..d3a8311 Binary files /dev/null and b/.hg/00changelog.i differ diff --git a/.hg/branch b/.hg/branch new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/.hg/branch @@ -0,0 +1 @@ +default diff --git a/.hg/cache/branch2-served b/.hg/cache/branch2-served new file mode 100644 index 0000000..ac7f03e --- /dev/null +++ b/.hg/cache/branch2-served @@ -0,0 +1,2 @@ +f955b00a6181dc5bdf0112fcaef09591a748fadd 25 +f955b00a6181dc5bdf0112fcaef09591a748fadd o default diff --git a/.hg/cache/rbc-names-v1 b/.hg/cache/rbc-names-v1 new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/.hg/cache/rbc-names-v1 @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/.hg/cache/rbc-revs-v1 b/.hg/cache/rbc-revs-v1 new file mode 100644 index 0000000..c3ab143 Binary files /dev/null and b/.hg/cache/rbc-revs-v1 differ diff --git a/.hg/dirstate b/.hg/dirstate new file mode 100644 index 0000000..998c764 Binary files /dev/null and b/.hg/dirstate differ diff --git a/.hg/hgrc b/.hg/hgrc new file mode 100644 index 0000000..6250142 --- /dev/null +++ b/.hg/hgrc @@ -0,0 +1,14 @@ +# example repository config (see "hg help config" for more info) +[paths] +default = ssh://hg@bitbucket.org/tyrelsouza/torchtester + +# path aliases to other clones of this repo in URLs or filesystem paths +# (see "hg help config.paths" for more info) +# +# default-push = ssh://jdoe@example.net/hg/jdoes-fork +# my-fork = ssh://jdoe@example.net/hg/jdoes-fork +# my-clone = /home/jdoe/jdoes-clone + +[ui] +# name and email (local to this repository, optional), e.g. +# username = Jane Doe diff --git a/.hg/requires b/.hg/requires new file mode 100644 index 0000000..f634f66 --- /dev/null +++ b/.hg/requires @@ -0,0 +1,4 @@ +dotencode +fncache +revlogv1 +store diff --git a/.hg/store/00changelog.i b/.hg/store/00changelog.i new file mode 100644 index 0000000..3ea6a21 Binary files /dev/null and b/.hg/store/00changelog.i differ diff --git a/.hg/store/00manifest.i b/.hg/store/00manifest.i new file mode 100644 index 0000000..bfb4d6d Binary files /dev/null and b/.hg/store/00manifest.i differ diff --git a/.hg/store/data/_program _files/_torch_tester/blank.png.i b/.hg/store/data/_program _files/_torch_tester/blank.png.i new file mode 100644 index 0000000..cf5896c Binary files /dev/null and b/.hg/store/data/_program _files/_torch_tester/blank.png.i differ diff --git a/.hg/store/data/_program _files/_torch_tester/green.png.i b/.hg/store/data/_program _files/_torch_tester/green.png.i new file mode 100644 index 0000000..739b58c Binary files /dev/null and b/.hg/store/data/_program _files/_torch_tester/green.png.i differ diff --git a/.hg/store/data/_program _files/_torch_tester/red.png.i b/.hg/store/data/_program _files/_torch_tester/red.png.i new file mode 100644 index 0000000..c032f8f Binary files /dev/null and b/.hg/store/data/_program _files/_torch_tester/red.png.i differ diff --git a/.hg/store/data/_r_e_a_d_m_e.txt.i b/.hg/store/data/_r_e_a_d_m_e.txt.i new file mode 100644 index 0000000..b5444b0 Binary files /dev/null and b/.hg/store/data/_r_e_a_d_m_e.txt.i differ diff --git a/.hg/store/data/_r_e_a_d_m_e.txt.txt.i b/.hg/store/data/_r_e_a_d_m_e.txt.txt.i new file mode 100644 index 0000000..0b5b2bb Binary files /dev/null and b/.hg/store/data/_r_e_a_d_m_e.txt.txt.i differ diff --git a/.hg/store/data/_torch_tester.fbp.i b/.hg/store/data/_torch_tester.fbp.i new file mode 100644 index 0000000..29490ed Binary files /dev/null and b/.hg/store/data/_torch_tester.fbp.i differ diff --git a/.hg/store/data/_torch_tester.sln.i b/.hg/store/data/_torch_tester.sln.i new file mode 100644 index 0000000..61c20ae Binary files /dev/null and b/.hg/store/data/_torch_tester.sln.i differ diff --git a/.hg/store/data/_torch_tester.suo.i b/.hg/store/data/_torch_tester.suo.i new file mode 100644 index 0000000..59e04a0 Binary files /dev/null and b/.hg/store/data/_torch_tester.suo.i differ diff --git a/.hg/store/data/_torch_tester/_program.py.i b/.hg/store/data/_torch_tester/_program.py.i new file mode 100644 index 0000000..efb6f87 Binary files /dev/null and b/.hg/store/data/_torch_tester/_program.py.i differ diff --git a/.hg/store/data/_torch_tester/_torch_d_b.i b/.hg/store/data/_torch_tester/_torch_d_b.i new file mode 100644 index 0000000..8b59be8 Binary files /dev/null and b/.hg/store/data/_torch_tester/_torch_d_b.i differ diff --git a/.hg/store/data/_torch_tester/_torch_tester.ico.i b/.hg/store/data/_torch_tester/_torch_tester.ico.i new file mode 100644 index 0000000..a437989 Binary files /dev/null and b/.hg/store/data/_torch_tester/_torch_tester.ico.i differ diff --git a/.hg/store/data/_torch_tester/_torch_tester.pyproj.i b/.hg/store/data/_torch_tester/_torch_tester.pyproj.i new file mode 100644 index 0000000..2068ace Binary files /dev/null and b/.hg/store/data/_torch_tester/_torch_tester.pyproj.i differ diff --git a/.hg/store/data/_torch_tester/_torch_tester.pyw.i b/.hg/store/data/_torch_tester/_torch_tester.pyw.i new file mode 100644 index 0000000..18f7c78 Binary files /dev/null and b/.hg/store/data/_torch_tester/_torch_tester.pyw.i differ diff --git a/.hg/store/data/_torch_tester/frm_main.py.i b/.hg/store/data/_torch_tester/frm_main.py.i new file mode 100644 index 0000000..eaf6248 Binary files /dev/null and b/.hg/store/data/_torch_tester/frm_main.py.i differ diff --git a/.hg/store/data/_torch_tester/initialization.py.i b/.hg/store/data/_torch_tester/initialization.py.i new file mode 100644 index 0000000..2a096e3 Binary files /dev/null and b/.hg/store/data/_torch_tester/initialization.py.i differ diff --git a/.hg/store/data/_torch_tester/logic.py.i b/.hg/store/data/_torch_tester/logic.py.i new file mode 100644 index 0000000..7e41c24 Binary files /dev/null and b/.hg/store/data/_torch_tester/logic.py.i differ diff --git a/.hg/store/data/_torch_tester/logic.pyc.i b/.hg/store/data/_torch_tester/logic.pyc.i new file mode 100644 index 0000000..2b66736 Binary files /dev/null and b/.hg/store/data/_torch_tester/logic.pyc.i differ diff --git a/.hg/store/data/_torch_tester/port__select.py.i b/.hg/store/data/_torch_tester/port__select.py.i new file mode 100644 index 0000000..506e6fe Binary files /dev/null and b/.hg/store/data/_torch_tester/port__select.py.i differ diff --git a/.hg/store/data/_torch_tester/port__select.pyc.i b/.hg/store/data/_torch_tester/port__select.pyc.i new file mode 100644 index 0000000..f29e81a Binary files /dev/null and b/.hg/store/data/_torch_tester/port__select.pyc.i differ diff --git a/.hg/store/data/_torch_tester/scanports.py.i b/.hg/store/data/_torch_tester/scanports.py.i new file mode 100644 index 0000000..9fb9b61 Binary files /dev/null and b/.hg/store/data/_torch_tester/scanports.py.i differ diff --git a/.hg/store/data/_torch_tester/scanports.pyc.i b/.hg/store/data/_torch_tester/scanports.pyc.i new file mode 100644 index 0000000..a2fd48a Binary files /dev/null and b/.hg/store/data/_torch_tester/scanports.pyc.i differ diff --git a/.hg/store/data/_torch_tester/test.pyc.i b/.hg/store/data/_torch_tester/test.pyc.i new file mode 100644 index 0000000..4c925a2 Binary files /dev/null and b/.hg/store/data/_torch_tester/test.pyc.i differ diff --git a/.hg/store/data/_torch_tester/wx_images.py.i b/.hg/store/data/_torch_tester/wx_images.py.i new file mode 100644 index 0000000..95670e7 Binary files /dev/null and b/.hg/store/data/_torch_tester/wx_images.py.i differ diff --git a/.hg/store/data/~2ehgignore.i b/.hg/store/data/~2ehgignore.i new file mode 100644 index 0000000..a7c3f49 Binary files /dev/null and b/.hg/store/data/~2ehgignore.i differ diff --git a/.hg/store/fncache b/.hg/store/fncache new file mode 100644 index 0000000..fe916a3 --- /dev/null +++ b/.hg/store/fncache @@ -0,0 +1,24 @@ +data/TorchTester/TorchDB.i +data/TorchTester/logic.py.i +data/TorchTester/logic.pyc.i +data/TorchTester/TorchTester.pyproj.i +data/TorchTester/test.pyc.i +data/Program Files/TorchTester/red.png.i +data/README.txt.txt.i +data/TorchTester/frmMain.py.i +data/TorchTester/port_select.pyc.i +data/TorchTester/wxImages.py.i +data/TorchTester/TorchTester.ico.i +data/TorchTester/initialization.py.i +data/.hgignore.i +data/Program Files/TorchTester/green.png.i +data/TorchTester/TorchTester.pyw.i +data/TorchTester/Program.py.i +data/README.txt.i +data/TorchTester.suo.i +data/TorchTester/scanports.pyc.i +data/TorchTester.sln.i +data/TorchTester.fbp.i +data/TorchTester/port_select.py.i +data/TorchTester/scanports.py.i +data/Program Files/TorchTester/blank.png.i diff --git a/.hg/store/phaseroots b/.hg/store/phaseroots new file mode 100644 index 0000000..e69de29 diff --git a/.hg/store/undo b/.hg/store/undo new file mode 100644 index 0000000..9668c9c Binary files /dev/null and b/.hg/store/undo differ diff --git a/.hg/store/undo.backupfiles b/.hg/store/undo.backupfiles new file mode 100644 index 0000000..ce173ce Binary files /dev/null and b/.hg/store/undo.backupfiles differ diff --git a/.hg/store/undo.phaseroots b/.hg/store/undo.phaseroots new file mode 100644 index 0000000..e69de29 diff --git a/.hg/undo.bookmarks b/.hg/undo.bookmarks new file mode 100644 index 0000000..e69de29 diff --git a/.hg/undo.branch b/.hg/undo.branch new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/.hg/undo.branch @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/.hg/undo.desc b/.hg/undo.desc new file mode 100644 index 0000000..5d422ab --- /dev/null +++ b/.hg/undo.desc @@ -0,0 +1,3 @@ +0 +pull +ssh://hg@bitbucket.org/tyrelsouza/torchtester diff --git a/.hg/undo.dirstate b/.hg/undo.dirstate new file mode 100644 index 0000000..e69de29 diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..4872e63 --- /dev/null +++ b/.hgignore @@ -0,0 +1,3 @@ +syntax:glob +*.pyc +TorchDB diff --git a/Program Files/TorchTester/blank.png b/Program Files/TorchTester/blank.png new file mode 100644 index 0000000..1c87878 Binary files /dev/null and b/Program Files/TorchTester/blank.png differ diff --git a/Program Files/TorchTester/green.png b/Program Files/TorchTester/green.png new file mode 100644 index 0000000..667d6ad Binary files /dev/null and b/Program Files/TorchTester/green.png differ diff --git a/Program Files/TorchTester/red.png b/Program Files/TorchTester/red.png new file mode 100644 index 0000000..d80f14a Binary files /dev/null and b/Program Files/TorchTester/red.png differ diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..c603eb1 --- /dev/null +++ b/README.txt @@ -0,0 +1,19 @@ +For this project we need to install: + + +Python2.7 [http://python.org/ftp/python/2.7.2/python-2.7.2.msi] +wxPython [http://downloads.sourceforge.net/wxpython/wxPython2.8-win32-unicode-2.8.12.1-py27.exe] +pyserial [http://sourceforge.net/projects/pyserial/files/pyserial/2.5/pyserial-2.5.win32.exe/download] + + + + +TODO: [Priority] + [8] Calculate Pass/fails + [6] Separate the panels with a border. + [6] Store the tests in the database. + [6] read thresholds settings from a file. + [2] Wrap everything up to a .exe file + [1] Create Installer + +Getting there! \ No newline at end of file diff --git a/TorchTester.fbp b/TorchTester.fbp new file mode 100644 index 0000000..5e32c30 --- /dev/null +++ b/TorchTester.fbp @@ -0,0 +1,1571 @@ + + + + + + C++ + 1 + source_name + 0 + UTF-8 + connect + + 1000 + none + 0 + MyProject1 + + . + + 1 + 1 + 0 + 0 + + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + frmMain + + 817,631 + wxDEFAULT_FRAME_STYLE + + Torch Tester + + + wxFILTER_NONE + wxDefaultValidator + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + formSizer + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + mainSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + 1 + + + 0 + wxID_ANY + + + m_panel2 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + + 1 + 1 + + + 0 + wxID_ANY + + + m_panel1 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + 2 + 0 + + gSizer3 + none + 2 + 0 + + 5 + wxEXPAND|wxRIGHT + 1 + + + + 1 + 1 + + + 0 + wxID_ANY + + + m_panel3 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + LeakSizerLeft + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + leakTitleSizer + wxVERTICAL + none + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + 1 + + Tahoma,90,90,22,74,1 + 0 + wxID_ANY + Leak + + + leakTitle + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + leakSizer1 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 1: SCCM: [ ] PASS Target Flow: [ ] Delta: [ ] + + + leak1 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + m_bitmap14 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + leakSizer2 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 2: SCCM: [ ] PASS Target Flow: [ ] Delta: [ ] + + + leak2 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgLeak2 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + leakSizer3 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 3: SCCM: [ ] PASS Target Flow: [ ] Delta: [ ] + + + leak3 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgLeak3 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + leakSizer4 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 4: SCCM: [ ] PASS Target Flow: [ ] Delta: [ ] + + + leak4 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgLeak4 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 150 + protected + 0 + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + + + 1 + 1 + + + 0 + wxID_ANY + + + m_panel6 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + FlowSizerRight + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + flowTitleSizer + wxVERTICAL + none + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + 1 + + Tahoma,90,90,22,74,1 + 0 + wxID_ANY + Flow + + + flowTitle + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + flowSizer1 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 1: SCCM: [ ] Target Flow: [ ] Delta: [ ] + + + flow1 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgFlow1 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + flowSizer2 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 2: SCCM: [ ] Target Flow: [ ] Delta: [ ] + + + flow2 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgFlow2 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + flowSizer3 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 3: SCCM: [ ] Target Flow: [ ] Delta: [ ] + + + flow3 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgFlow3 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + flowSizer4 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + Tahoma,90,90,12,74,0 + 0 + wxID_ANY + Test 4: SCCM: [ ] Target Flow: [ ] Delta: [ ] + + + flow4 + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + ; Load From File + + 1 + 1 + + + 0 + wxID_ANY + + + imgFlow4 + protected + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + + + + + 5 + wxEXPAND + 0 + + 0 + protected + 800 + + + + + + + 1 + 1 + + + 0 + wxID_ANY + MyMenuBar + + + mnuMainBar + protected + + + + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &Options + mnuOptions + protected + + + + + + 1 + 1 + + 1 + + 0 + wxID_ANY + + + m_statusBar1 + protected + + + wxST_SIZEGRIP + + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TorchTester.sln b/TorchTester.sln new file mode 100644 index 0000000..37079f3 --- /dev/null +++ b/TorchTester.sln @@ -0,0 +1,18 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "TorchTester", "TorchTester\TorchTester.pyproj", "{A172B229-11F0-4265-9205-FA5A8EC52471}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A172B229-11F0-4265-9205-FA5A8EC52471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A172B229-11F0-4265-9205-FA5A8EC52471}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/TorchTester.suo b/TorchTester.suo new file mode 100644 index 0000000..c114d02 Binary files /dev/null and b/TorchTester.suo differ diff --git a/TorchTester/Program.py b/TorchTester/Program.py new file mode 100644 index 0000000..9c0879f --- /dev/null +++ b/TorchTester/Program.py @@ -0,0 +1,140 @@ +""" + Author: Tyrel Souza + + TO DO: + Watch for "Stop Button Pressed" + if test is pass, show colors red and green + If index of combo box is changed, + change all visible combo boxes. + Box for Name + Map Button + (have defaults saved) + pop up page to enter in Progra Number, Test Number, Set target sccm + Sync button on bottom + ex: write " asdfjasdf jsadf js #2\r\n" + write " asdfsadjf askjdf kasf 3.0" + deferreds +""" +import wx +import sqlite3 as sqlite +import logic +import serial +import scanports +import os +import io +import ConfigParser +import pdb +import sys +from threading import * +from frmMain import frmMain + +EXITMETHOD = ["Unknown","Completed","Stop Button","Severe Leak"] +global DEBUG +DEBUG = True +APPNAME = "TorchTester" + +class settings(): + COMPORT = "COM3" # This is the default comport. + BAUDRATE = 115200 + BYTESIZE = serial.EIGHTBITS + PARITY = serial.PARITY_NONE + STOPBITS = serial.STOPBITS_ONE + DIR = os.path.join(os.environ['APPDATA'], APPNAME) + CONFIG_FILE = os.path.join(os.environ['APPDATA'], APPNAME) + '\\config.ini' + DB_FILE = os.path.join(os.environ['APPDATA'], APPNAME) + '\\Torch.sqlite' + ICON_FILE = os.path.join(os.environ['APPDATA'], APPNAME) + "\HyperTherm.ico" + + def __init__(self): + if not os.path.exists(self.DIR): + os.makedirs(self.DIR) + with open(self.CONFIG_FILE,'w') as f: + inifile = """[LEAK] +LEAKA = 2.0 +LEAKB = 2.0 +LEAKC = 2.0 +LEAKD = 2.0 +[FLOW] +FLOWA = 28000 +FLOWB = 28000 +FLOWC = 28000 +FLOWD = 78000""" + f.write(inifile) + f.close + + + def get_limits(self,runno=None,settings=None): + try: + parser = ConfigParser.ConfigParser() + parser.read(settings.CONFIG_FILE) + limits = [] + limits.append([None,parser.get('LEAK','LEAKA')]) + limits.append([None,parser.get('LEAK','LEAKB')]) + limits.append([None,parser.get('LEAK','LEAKC')]) + limits.append([None,parser.get('LEAK','LEAKD')]) + limits.append([None,parser.get('FLOW','FLOWA')]) + limits.append([None,parser.get('FLOW','FLOWB')]) + limits.append([None,parser.get('FLOW','FLOWC')]) + limits.append([None,parser.get('FLOW','FLOWD')]) + except: + limits = [] + limits.append(['LEAKA','2.0']) + limits.append(['LEAKB','2.0']) + limits.append(['LEAKC','2.0']) + limits.append(['LEAKD','2.0']) + limits.append(['FLOWA','28000']) + limits.append(['FLOWB','28000']) + limits.append(['FLOWC','28000']) + limits.append(['FLOWD','78000']) + + limit = limits[runno][1] + + + return limit + +def main(settings): + app = wx.App() + frame = frmMain(None,settings) + frame.Show() + app.SetTopWindow(frame) + app.MainLoop() + +def check_db(s): + """ + This function will select the LAST set comport in the database. + If there is no last set comport, it will prompt you for your comports, + then it will accept the comport and save it to the database. + """ + conn = sqlite.connect(s.DB_FILE,detect_types=sqlite.PARSE_DECLTYPES) + c = conn.cursor() + try: + c.execute('SELECT CASE WHEN tbl_name = "torch_record" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "torch_record" AND type = "table"') + table_exists = c.fetchone() + if not table_exists: + + c.execute("CREATE TABLE torch_record (id INTEGER PRIMARY KEY AUTOINCREMENT, port_number TEXT, program_number TEXT, test_date DATE, test_time TEXT, measurement REAL,result TEXT)"); + c.execute('SELECT CASE WHEN tbl_name = "torch_record" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "torch_record" AND type = "table"') + table_exists = c.fetchone() + + except sqlite.OperationalError, e: + print e + c.close() + return s + +def run_test(settings): + ser = logic.connect_serial_and_open(settings) + try: + # listen to what's happeneing on the serial port. + EM,out = logic.read_serial(ser) + except Exception, ex: + ser.close() + try: + ser.close() + except: + pass + return EM,out + +if __name__ == "__main__": + settings = settings() + settings = check_db(settings) + main(settings) + diff --git a/TorchTester/TorchTester.ico b/TorchTester/TorchTester.ico new file mode 100644 index 0000000..f303825 Binary files /dev/null and b/TorchTester/TorchTester.ico differ diff --git a/TorchTester/TorchTester.pyproj b/TorchTester/TorchTester.pyproj new file mode 100644 index 0000000..11be918 --- /dev/null +++ b/TorchTester/TorchTester.pyproj @@ -0,0 +1,32 @@ + + + + Debug + 2.0 + {a172b229-11f0-4265-9205-fa5a8ec52471} + . + Program.py + + + . + TorchTester + TorchTester + TorchTester + + + true + false + + + true + false + + + + + + + + + + \ No newline at end of file diff --git a/TorchTester/TorchTester.pyw b/TorchTester/TorchTester.pyw new file mode 100644 index 0000000..d07b0a6 --- /dev/null +++ b/TorchTester/TorchTester.pyw @@ -0,0 +1,127 @@ +""" + Author: Tyrel Souza + + TO DO: + Watch for "Stop Button Pressed" + if test is pass, show colors red and green + If index of combo box is changed, + change all visible combo boxes. + Box for Name + Map Button + (have defaults saved) + pop up page to enter in Progra Number, Test Number, Set target sccm + Sync button on bottom + ex: write " asdfjasdf jsadf js #2\r\n" + write " asdfsadjf askjdf kasf 3.0" + deferreds +""" +import wx +import sqlite3 as sqlite +import logic +import serial +import scanports +import os +import io +import ConfigParser +import pdb +import sys +from threading import * +from frmMain import frmMain + +EXITMETHOD = ["Unknown","Completed","Stop Button","Severe Leak"] +global DEBUG +DEBUG = True +APPNAME = "TorchTester" + +class settings(): + COMPORT = "COM1" # This is the default comport. + BAUDRATE = 115200 + BYTESIZE = serial.EIGHTBITS + PARITY = serial.PARITY_NONE + STOPBITS = serial.STOPBITS_ONE + DIR = os.path.join(os.environ['APPDATA'], APPNAME) + CONFIG_FILE = os.path.join(os.environ['APPDATA'], APPNAME) + '\\config.ini' + DB_FILE = os.path.join(os.environ['APPDATA'], APPNAME) + '\\Torch.sqlite' + ICON_FILE = os.path.join(os.environ['APPDATA'], APPNAME) + "\HyperTherm.ico" + + def __init__(self): + if not os.path.exists(self.DIR): + os.makedirs(self.DIR) + + + def get_limits(self,runno=None,settings=None): + try: + parser = ConfigParser.ConfigParser() + parser.read(settings.CONFIG_FILE) + limits = [] + limits.append([None,parser.get('LEAK','LEAKA')]) + limits.append([None,parser.get('LEAK','LEAKB')]) + limits.append([None,parser.get('LEAK','LEAKC')]) + limits.append([None,parser.get('LEAK','LEAKD')]) + limits.append([None,parser.get('FLOW','FLOWA')]) + limits.append([None,parser.get('FLOW','FLOWB')]) + limits.append([None,parser.get('FLOW','FLOWC')]) + limits.append([None,parser.get('FLOW','FLOWD')]) + except: + limits = [] + limits.append(['LEAKA','2.0']) + limits.append(['LEAKB','2.0']) + limits.append(['LEAKC','2.0']) + limits.append(['LEAKD','2.0']) + limits.append(['FLOWA','28000']) + limits.append(['FLOWB','28000']) + limits.append(['FLOWC','28000']) + limits.append(['FLOWD','78000']) + + limit = limits[runno][1] + + + return limit + +def main(settings): + app = wx.App() + frame = frmMain(None,settings) + frame.Show() + app.SetTopWindow(frame) + app.MainLoop() + +def check_db(s): + """ + This function will select the LAST set comport in the database. + If there is no last set comport, it will prompt you for your comports, + then it will accept the comport and save it to the database. + """ + conn = sqlite.connect(s.DB_FILE,detect_types=sqlite.PARSE_DECLTYPES) + c = conn.cursor() + try: + c.execute('SELECT CASE WHEN tbl_name = "torch_record" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "torch_record" AND type = "table"') + table_exists = c.fetchone() + if not table_exists: + + c.execute("CREATE TABLE torch_record (id INTEGER PRIMARY KEY AUTOINCREMENT, port_number TEXT, program_number TEXT, test_date DATE, test_time TEXT, measurement REAL,result TEXT)"); + c.execute('SELECT CASE WHEN tbl_name = "torch_record" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "torch_record" AND type = "table"') + table_exists = c.fetchone() + + except sqlite.OperationalError, e: + print e + c.close() + return s + +def run_test(settings): + ser = logic.connect_serial_and_open(settings) + try: + # listen to what's happeneing on the serial port. + EM,out = logic.read_serial(ser) + except Exception, ex: + ser.close() + try: + ser.close() + except: + pass + return EM,out + +if __name__ == "__main__": + settings = settings() + settings = check_db(settings) + main(settings) + diff --git a/TorchTester/frmMain.py b/TorchTester/frmMain.py new file mode 100644 index 0000000..4eba576 --- /dev/null +++ b/TorchTester/frmMain.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- + +########################################################################### +## Python code generated with wxFormBuilder (version Sep 8 2010) +## http://www.wxformbuilder.org/ +## +## PLEASE DO "NOT" EDIT THIS FILE! +########################################################################### + +import wx +import logic +import thread +import time +import datetime +import subprocess +from wx.lib.wordwrap import wordwrap +########################################################################### +## Class frmMain +########################################################################### + +class frmMain ( wx.Frame ): + + + def __init__( self, parent,settings): + self.settings = settings + + wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Torch Tester", + pos = wx.DefaultPosition, size = wx.Size( 925,631 ), style = wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CAPTION | wx.MINIMIZE_BOX ) + favicon = wx.Icon(settings.ICON_FILE, + wx.BITMAP_TYPE_ICO) + self.SetIcon(favicon) + + + + self.Bind(wx.EVT_CLOSE, self.onClose) + self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize ) + + formSizer = wx.BoxSizer( wx.VERTICAL ) + + mainSizer = wx.BoxSizer( wx.VERTICAL ) + + self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + mainSizer.Add( self.m_panel2, 1, wx.EXPAND, 5 ) + + formSizer.Add( mainSizer, 0, wx.EXPAND, 5 ) + + self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) + gSizer3 = wx.GridSizer( 2, 4, 0, 0 ) + + LeakSizerLeft = wx.BoxSizer( wx.VERTICAL ) + + leakTitleSizer = wx.BoxSizer( wx.VERTICAL ) + + self.leakTitle = wx.StaticText( self.m_panel1, wx.ID_ANY, u"Leak", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.leakTitle.Wrap( -1 ) + self.leakTitle.SetFont( wx.Font( 22, 74, 90, 90, True, "Tahoma" ) ) + + leakTitleSizer.Add( self.leakTitle, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + LeakSizerLeft.Add( leakTitleSizer, 0, wx.EXPAND, 5 ) + + leakSizer1 = wx.BoxSizer( wx.HORIZONTAL ) + + self.leak1 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.leak1.Wrap( -1 ) + self.leak1.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgLeak1 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY|wx.ALIGN_RIGHT, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + leakSizer1.Add( self.imgLeak1, 1, wx.ALL, 5) + leakSizer1.Add( self.leak1, 0, wx.ALL, 5 ) + LeakSizerLeft.Add( leakSizer1, 1, wx.EXPAND, 5 ) + + + leakSizer2 = wx.BoxSizer( wx.HORIZONTAL ) + self.leak2 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.leak2.Wrap( -1 ) + self.leak2.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgLeak2 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + leakSizer2.Add( self.imgLeak2, 1, wx.ALL, 5 ) + leakSizer2.Add( self.leak2, 0, wx.ALL, 5 ) + LeakSizerLeft.Add( leakSizer2, 1, wx.EXPAND, 5 ) + + leakSizer3 = wx.BoxSizer( wx.HORIZONTAL ) + self.leak3 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.leak3.Wrap( -1 ) + self.leak3.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgLeak3 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + leakSizer3.Add( self.imgLeak3, 1, wx.ALL, 5 ) + leakSizer3.Add( self.leak3, 0, wx.ALL, 5 ) + LeakSizerLeft.Add( leakSizer3, 1, wx.EXPAND, 5 ) + + leakSizer4 = wx.BoxSizer( wx.HORIZONTAL ) + self.leak4 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.leak4.Wrap( -1 ) + self.leak4.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgLeak4 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + leakSizer4.Add( self.imgLeak4, 1, wx.ALL, 5 ) + leakSizer4.Add( self.leak4, 0, wx.ALL, 5 ) + LeakSizerLeft.Add( leakSizer4, 1, wx.EXPAND, 5 ) + + + LeakSizerLeft.AddSpacer( ( 0, 150), 1, wx.EXPAND, 5 ) + + gSizer3.Add( LeakSizerLeft, 0, wx.EXPAND|wx.RIGHT, 5 ) + + gSizer3.AddSpacer( ( 18, 0), 1, wx.EXPAND, 5 ) + + FlowSizerRight = wx.BoxSizer( wx.VERTICAL ) + + flowTitleSizer = wx.BoxSizer( wx.VERTICAL ) + + self.flowTitle = wx.StaticText( self.m_panel1, wx.ID_ANY, u"Flow", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.flowTitle.Wrap( -1 ) + self.flowTitle.SetFont( wx.Font( 22, 74, 90, 90, True, "Tahoma" ) ) + + flowTitleSizer.Add( self.flowTitle, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) + + FlowSizerRight.Add( flowTitleSizer, 0, wx.EXPAND, 5 ) + + + + + + flowSizer1 = wx.BoxSizer( wx.HORIZONTAL ) + self.flow1 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.flow1.Wrap( -1 ) + self.flow1.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgFlow1 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + flowSizer1.Add( self.imgFlow1, 1, wx.ALL, 5 ) + flowSizer1.Add( self.flow1, 0, wx.ALL, 5 ) + FlowSizerRight.Add( flowSizer1, 1, wx.EXPAND, 5 ) + + + + + flowSizer2 = wx.BoxSizer( wx.HORIZONTAL ) + self.flow2 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.flow2.Wrap( -1 ) + self.flow2.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgFlow2 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + flowSizer2.Add( self.imgFlow2, 1, wx.ALL, 5 ) + flowSizer2.Add( self.flow2, 0, wx.ALL, 5 ) + FlowSizerRight.Add( flowSizer2, 1, wx.EXPAND, 5 ) + + + + + + flowSizer3 = wx.BoxSizer( wx.HORIZONTAL ) + self.flow3 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.flow3.Wrap( -1 ) + self.flow3.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgFlow3 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + flowSizer3.Add( self.imgFlow3, 1, wx.ALL, 5 ) + flowSizer3.Add( self.flow3, 0, wx.ALL, 5 ) + FlowSizerRight.Add( flowSizer3, 1, wx.EXPAND, 5 ) + + + + flowSizer4 = wx.BoxSizer( wx.HORIZONTAL ) + self.flow4 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"", wx.DefaultPosition, wx.DefaultSize, 0 ) + self.flow4.Wrap( -1 ) + self.flow4.SetFont( wx.Font( 12, 74, 90, 90, False, "Tahoma" ) ) + self.imgFlow4 = wx.StaticBitmap( self.m_panel1, wx.ID_ANY, wx.NullBitmap, wx.DefaultPosition, wx.DefaultSize, 0 ) + flowSizer4.Add( self.imgFlow4, 1, wx.ALL, 5 ) + flowSizer4.Add( self.flow4, 0, wx.ALL, 5 ) + FlowSizerRight.Add( flowSizer4, 1, wx.EXPAND, 5 ) + + + FlowSizerRight.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 ) + + gSizer3.Add( FlowSizerRight, 0, wx.EXPAND|wx.LEFT, 5 ) + + self.m_panel1.SetSizer( gSizer3 ) + self.m_panel1.Layout() + gSizer3.Fit( self.m_panel1 ) + formSizer.Add( self.m_panel1, 1, wx.EXPAND, 5 ) + + + formSizer.AddSpacer( ( 1024 , 0), 0, wx.EXPAND, 5 ) + + self.SetSizer( formSizer ) + self.Layout() + self.mnuMainBar = wx.MenuBar( 0 ) + self.mnuOptions = wx.Menu() + + self.m_sqlite = wx.MenuItem( self.mnuOptions, wx.ID_ANY, u"SQLite Browser", wx.EmptyString, wx.ITEM_NORMAL ) + self.Bind(wx.EVT_MENU, self.sqlite_browser, self.m_sqlite) + self.mnuOptions.AppendItem( self.m_sqlite ) + + + self.about = wx.MenuItem( self.mnuOptions, wx.ID_ANY, u"&About", wx.EmptyString, wx.ITEM_NORMAL ) + self.Bind(wx.EVT_MENU, self.about_button, self.about) + self.mnuOptions.AppendItem( self.about ) + + + + self.m_exit = wx.MenuItem( self.mnuOptions, wx.ID_ANY, u"E&xit", wx.EmptyString, wx.ITEM_NORMAL ) + self.Bind(wx.EVT_MENU, self.onClose, self.m_exit) + self.mnuOptions.AppendItem( self.m_exit ) + + self.mnuMainBar.Append( self.mnuOptions, u"&Options" ) + self.SetMenuBar( self.mnuMainBar ) + + #self.m_statusBar1 = self.CreateStatusBar( 1, wx.ST_SIZEGRIP, wx.ID_ANY ) + + self.Centre( wx.BOTH ) + thread.start_new_thread(WorkerThread,(self,settings,)) + + def __del__( self ): + self.destroy() + pass + + def onClose(self,event): + self.Destroy() + + + def about_button(self, evt): + # First we create and fill the info object + info = wx.AboutDialogInfo() + info.Name = "TorchTester" + info.Version = "1.0.0.1" + info.Copyright = "(C) 2011 Benchtop Devices LLC" + info.Description = wordwrap(""" +This program monitors the CTS Blackbelt. +In the left column are leak tests, and on the right are flow tests. +The tests are compared with default values found in config.ini (an example of which is provided for you in the %APPDATA%/TorchTester/ directory) + +In the config.ini file, the leak value is the highest value to pass, and the flow is the lowest value to pass. + +To view the database, select SQLite Browser from the Options menu. + + """, + # change the wx.ClientDC to use self.panel instead of self + 350, wx.ClientDC(self)) + info.WebSite = ("http://www.benchtopdevices.com", "Benchtop Devices") + info.Developers = [ "Tyrel Souza", + "Anthony Souza"] + + + # Then we call wx.AboutBox giving it that info object + wx.AboutBox(info) + + + def sqlite_browser(self,event): + p1=subprocess.Popen(self.settings.DIR + '\\SQLiteBrowser\\SQLiteBrowser.exe "'+self.settings.DB_FILE+'"') + + + +def WorkerThread(self,settings): + while True: + logic.run_test(self,settings) diff --git a/TorchTester/initialization.py b/TorchTester/initialization.py new file mode 100644 index 0000000..e9e8522 --- /dev/null +++ b/TorchTester/initialization.py @@ -0,0 +1,39 @@ +import wx +import os +APPNAME = "TorchTester" + + +def clear(wxObj): + wx.CallAfter(wxObj.flow1.SetLabel, '') + wx.CallAfter(wxObj.flow2.SetLabel, '') + wx.CallAfter(wxObj.flow3.SetLabel, '') + wx.CallAfter(wxObj.flow4.SetLabel, '') + wx.CallAfter(wxObj.leak1.SetLabel, '') + wx.CallAfter(wxObj.leak2.SetLabel, '') + wx.CallAfter(wxObj.leak3.SetLabel, '') + wx.CallAfter(wxObj.leak4.SetLabel, '') + + + wx.CallAfter(wxObj.imgFlow1.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgFlow1.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgFlow2.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgFlow2.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgFlow3.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgFlow3.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgFlow4.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgFlow4.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgLeak1.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgLeak1.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgLeak2.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgLeak2.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgLeak3.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgLeak3.SetSize, (72,72)) + + wx.CallAfter(wxObj.imgLeak4.SetBitmap, (wx.Bitmap(os.path.join(os.environ['APPDATA'], APPNAME) +'\\blank.png'))) + wx.CallAfter(wxObj.imgLeak4.SetSize, (72,72)) \ No newline at end of file diff --git a/TorchTester/logic.py b/TorchTester/logic.py new file mode 100644 index 0000000..ba270ec --- /dev/null +++ b/TorchTester/logic.py @@ -0,0 +1,248 @@ +import wx +import time +import datetime +import serial +import platform +import sqlite3 +import initialization as ini +from decimal import Decimal +import locale + +#EXITMETHOD = ["Unknown","Completed","Stop Button","Severe Leak"] + +leak_template = """Test %s: + Actual Leak: %s sccm + Target Leak: %s + Delta: %s""" +flow_template = """Test %s: + Actual Flow: %s sccm + Target Flow: %s + Delta: %s""" + + + +def connect_serial_and_open(s): + """ + This function will determine if thecomputer is running Windows + or Linux, and set the Serial port appropriately. + Then it will setup the serial port as 8-n-1 and 115200 baud. + This function then checks if the serial port is not open, + if it is not, it opens it and returns the serial port object. + """ + ser = serial.Serial() + # Set up 15200 8-N-1 + ser.port = s.COMPORT + ser.baudrate = s.BAUDRATE + ser.bytesize = s.BYTESIZE + ser.parity = s.PARITY + ser.stopbits = s.STOPBITS + + if not ser.isOpen(): + ser.open() + return ser + +#71E1011 T Start Streaming + +def run_test(wxObj,settings): + ser = connect_serial_and_open(settings) + test = 0 + for run,exit in read_serial(ser,wxObj): + + test += 1 + if exit == 1 or exit == 0: + if isinstance(run,dict): + runno = int(run['run_number']) + _runs=('A','B','C','D') + if runno < 4: + for k,v in enumerate(_runs): + if k == runno: + tol,delta = passes(run,settings,wxObj,runno) + delta = "%.2f" % delta + lbl = leak_template % (v, str(round(float(run['sccm']),2)),tol,delta) + wx.CallAfter(wxObj.leak1.SetLabel, lbl) + + else: + for k,v in enumerate(_runs): + if k+4 == runno: + sccm = float(run['sccm']) + tol,delta = passes(run,settings,wxObj,runno) + sccm = intWithCommas(sccm) + tol = intWithCommas(tol) + delta= intWithCommas(delta) + + lbl = flow_template % (v, sccm,tol,delta) + wx.CallAfter(wxObj.flow1.SetLabel, lbl) + + else: + msg = None + if exit == 2 and run == 'SB': + msg = 'STOP BUTTON PRESSED' + elif exit == 3 and run == 'SL': + msg = 'SEVERE LEAK' + elif exit == 4 and run == 'MISC': + msg = 'BELOW PRESSURE' + + if msg: + if test < 5: + if test ==1: + ini.clear(wxObj) + wx.CallAfter( getattr(wxObj, 'lead%s' % test).SetLabel, msg) + else: + wx.CallAfter( getattr(wxObj, 'flow%s' % test - 4).SetLabel, msg) + return None + + + +def read_serial(ser=None,wxObj=None): + STOP = False + ExitMethod = 0 + if ser and ser.isOpen() and wxObj: + buffer = '' + run_number = -1 + while not STOP: + sent = False + buffer = buffer + ser.read(1) + last_list = buffer.partition('\r\n') + if last_list[1]: + last_received = last_list[0] + output = parse_line(last_received) + if output == "SB": + STOP = True + ExitMethod = 2 + elif output == "SL": + STOP = True + ExitMethod = 3 + elif output == "MISC": + STOP = True + ExitMethod = 4 + elif output: + if run_number < 0: + ini.clear(wxObj) + run_number +=1 + output['run_number'] = run_number + if run_number == 8: + STOP = True + ExitMethod = 1 + yield output,ExitMethod + continue + # P12 is a dummy test to release pressure between 7 and 8, so we must ignore that. + if not output['program_number'] == "P12": + sent = True + yield output,ExitMethod + if output and not sent: + try: + yield output,ExitMethod + except GeneratorExit: + pass + buffer = last_list[2] + + +def parse_line(line_to_parse,last_program_number=None ): + # strip all whitespace from end of line + #if there remains anything, continue on. + if line_to_parse: + # actually store result as a list of strings, split by \t + try: + if "TTY Pressure Decay-L" in line_to_parse: + return "MISC" + result = line_to_parse.rstrip().split('\t') + # check if the list is equal to 3, and that "R" is the 2nd item + if len(result) == 3 and "R" in result[1]: + # If R is the second item, split Result by spaces. + l = result[2].split(' ') + # Remove all blank items in the list + l = [item for item in l if item] + # There will be a summary as the last item, if this is so, + # Skip the item and return None + if l[4] == "SB": + return "SB" + if l[4] == "SL": + return "SL" + if l[5] == "LNK": + return None + + # Prepare a dictionary with the keys and values + # we yanked from the test + out_result = {} + out_result['port_number'] = l[0] + out_result['program_number'] = l[1] + out_result['run_datetime'] = datetime.datetime.strptime( + "%s %s" % (l[2], l[3]), "%H:%M:%S.%f %m/%d/%y") + out_result['evaluation'] = l[6] + out_result['sccm'] = l[8] + + if out_result: + return out_result + except: + pass + +def passes(run,settings,wxObj,runno): + GREEN = wx.Bitmap(settings.DIR + '\\green.png') + RED = wx.Bitmap(settings.DIR + '\\red.png') + for i in range(0,9): + if i > 9: + raise AttributeError('Not sure what this all means, but I dont think we can continute') + if i < 4: + tol,delta,pass_or_fail=withinTolerance(run,settings,run['run_number']) + color = GREEN if pass_or_fail else RED + wx.CallAfter(getattr(wxObj, 'imgLeak%s' % i +1).SetBitmap, (color)) + else: + tol,delta,pass_or_fail=withinTolerance(run,settings,run['run_number']) + color = GREEN if pass_or_fail else RED + wx.CallAfter( getattr(wxObj,'imgFlow%s'% i -4).SetBitmap, (color)) + return tol,delta + + +def withinTolerance(run,settings,runno): + tol = Decimal(settings.get_limits(runno,settings)) + sccm = Decimal(run['sccm']) + passes = False + if runno < 4: + delta = sccm - tol + if sccm < tol: + passes = True + else: + delta = tol - sccm + if sccm > tol: + passes = True + delta = abs(delta) + + rundate = run['run_datetime'].date() + runtime = str(run['run_datetime'].time()) + + + if passes: + passes_ar = "A" + else: + passes_ar = "R" + results = [run['port_number'], + run['program_number'], + rundate, + runtime, + run['sccm'], + passes_ar] + + conn = sqlite3.connect(settings.DB_FILE,detect_types=sqlite3.PARSE_DECLTYPES) + c = conn.cursor() + c.execute("INSERT INTO torch_record (port_number,program_number,test_date,test_time,measurement,result) VALUES(?,?,?,?,?,?)",results) + conn.commit() + c.close() + + + + + return tol,delta,passes + + + +def intWithCommas(x): + x = int(x) + if type(x) not in [type(0), type(0L)]: + raise TypeError("Parameter must be an integer.") + if x < 0: + return '-' + intWithCommas(-x) + result = '' + while x >= 1000: + x, r = divmod(x, 1000) + result = ",%03d%s" % (r, result) + return "%d%s" % (x, result) diff --git a/TorchTester/scanports.py b/TorchTester/scanports.py new file mode 100644 index 0000000..733545d --- /dev/null +++ b/TorchTester/scanports.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python +"""\ +Scan for serial ports. + +Part of pySerial (http://pyserial.sf.net) +(C) 2002-2003 + +The scan function of this module tries to open each port number +from 0 to 255 and it builds a list of those ports where this was +successful. +""" + +import serial +import glob +import sys + +def win_scan(): + """scan for available ports. return a list of tuples (num, name)""" + available = [] + for i in range(256): + try: + s = serial.Serial(i) + available.append( (i, s.portstr)) + s.close() # explicit close 'cause of delayed GC in java + except serial.SerialException: + pass + return available + +def get(): + ports = [] + if sys.platform.startswith('win'): + for n,s in win_scan(): + ports.append(s) + else: + for name in lin_scan(): + ports.append(name) + return ports + + +def lin_scan(): + """scan for available ports. return a list of device names.""" + return glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + diff --git a/TorchTester/wxImages.py b/TorchTester/wxImages.py new file mode 100644 index 0000000..2299e1e --- /dev/null +++ b/TorchTester/wxImages.py @@ -0,0 +1,221 @@ +#---------------------------------------------------------------------- +# This file was generated by img2py.py +# +from wx.lib.embeddedimage import PyEmbeddedImage + +red = PyEmbeddedImage( + "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" + "/wNREk1547u9MgAAAABJRU5ErkJggg==") +getredData = red.GetData +getredImage = red.GetImage +getredBitmap = red.GetBitmap +getredIcon = red.GetIcon + + + +green = PyEmbeddedImage( + "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") +getgreenData = green.GetData +getgreenImage = green.GetImage +getgreenBitmap = green.GetBitmap +getgreenIcon = green.GetIcon +