t push -u origin master
This commit is contained in:
commit
1b565ebb07
BIN
.hg/00changelog.i
Normal file
BIN
.hg/00changelog.i
Normal file
Binary file not shown.
1
.hg/branch
Normal file
1
.hg/branch
Normal file
@ -0,0 +1 @@
|
|||||||
|
default
|
2
.hg/cache/branch2-served
vendored
Normal file
2
.hg/cache/branch2-served
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
f955b00a6181dc5bdf0112fcaef09591a748fadd 25
|
||||||
|
f955b00a6181dc5bdf0112fcaef09591a748fadd o default
|
1
.hg/cache/rbc-names-v1
vendored
Normal file
1
.hg/cache/rbc-names-v1
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
default
|
BIN
.hg/cache/rbc-revs-v1
vendored
Normal file
BIN
.hg/cache/rbc-revs-v1
vendored
Normal file
Binary file not shown.
BIN
.hg/dirstate
Normal file
BIN
.hg/dirstate
Normal file
Binary file not shown.
14
.hg/hgrc
Normal file
14
.hg/hgrc
Normal file
@ -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 <jdoe@example.com>
|
4
.hg/requires
Normal file
4
.hg/requires
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
dotencode
|
||||||
|
fncache
|
||||||
|
revlogv1
|
||||||
|
store
|
BIN
.hg/store/00changelog.i
Normal file
BIN
.hg/store/00changelog.i
Normal file
Binary file not shown.
BIN
.hg/store/00manifest.i
Normal file
BIN
.hg/store/00manifest.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_program _files/_torch_tester/blank.png.i
Normal file
BIN
.hg/store/data/_program _files/_torch_tester/blank.png.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_program _files/_torch_tester/green.png.i
Normal file
BIN
.hg/store/data/_program _files/_torch_tester/green.png.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_program _files/_torch_tester/red.png.i
Normal file
BIN
.hg/store/data/_program _files/_torch_tester/red.png.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_r_e_a_d_m_e.txt.i
Normal file
BIN
.hg/store/data/_r_e_a_d_m_e.txt.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_r_e_a_d_m_e.txt.txt.i
Normal file
BIN
.hg/store/data/_r_e_a_d_m_e.txt.txt.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester.fbp.i
Normal file
BIN
.hg/store/data/_torch_tester.fbp.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester.sln.i
Normal file
BIN
.hg/store/data/_torch_tester.sln.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester.suo.i
Normal file
BIN
.hg/store/data/_torch_tester.suo.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/_program.py.i
Normal file
BIN
.hg/store/data/_torch_tester/_program.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/_torch_d_b.i
Normal file
BIN
.hg/store/data/_torch_tester/_torch_d_b.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/_torch_tester.ico.i
Normal file
BIN
.hg/store/data/_torch_tester/_torch_tester.ico.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/_torch_tester.pyproj.i
Normal file
BIN
.hg/store/data/_torch_tester/_torch_tester.pyproj.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/_torch_tester.pyw.i
Normal file
BIN
.hg/store/data/_torch_tester/_torch_tester.pyw.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/frm_main.py.i
Normal file
BIN
.hg/store/data/_torch_tester/frm_main.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/initialization.py.i
Normal file
BIN
.hg/store/data/_torch_tester/initialization.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/logic.py.i
Normal file
BIN
.hg/store/data/_torch_tester/logic.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/logic.pyc.i
Normal file
BIN
.hg/store/data/_torch_tester/logic.pyc.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/port__select.py.i
Normal file
BIN
.hg/store/data/_torch_tester/port__select.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/port__select.pyc.i
Normal file
BIN
.hg/store/data/_torch_tester/port__select.pyc.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/scanports.py.i
Normal file
BIN
.hg/store/data/_torch_tester/scanports.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/scanports.pyc.i
Normal file
BIN
.hg/store/data/_torch_tester/scanports.pyc.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/test.pyc.i
Normal file
BIN
.hg/store/data/_torch_tester/test.pyc.i
Normal file
Binary file not shown.
BIN
.hg/store/data/_torch_tester/wx_images.py.i
Normal file
BIN
.hg/store/data/_torch_tester/wx_images.py.i
Normal file
Binary file not shown.
BIN
.hg/store/data/~2ehgignore.i
Normal file
BIN
.hg/store/data/~2ehgignore.i
Normal file
Binary file not shown.
24
.hg/store/fncache
Normal file
24
.hg/store/fncache
Normal file
@ -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
|
0
.hg/store/phaseroots
Normal file
0
.hg/store/phaseroots
Normal file
BIN
.hg/store/undo
Normal file
BIN
.hg/store/undo
Normal file
Binary file not shown.
BIN
.hg/store/undo.backupfiles
Normal file
BIN
.hg/store/undo.backupfiles
Normal file
Binary file not shown.
0
.hg/store/undo.phaseroots
Normal file
0
.hg/store/undo.phaseroots
Normal file
0
.hg/undo.bookmarks
Normal file
0
.hg/undo.bookmarks
Normal file
1
.hg/undo.branch
Normal file
1
.hg/undo.branch
Normal file
@ -0,0 +1 @@
|
|||||||
|
default
|
3
.hg/undo.desc
Normal file
3
.hg/undo.desc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
0
|
||||||
|
pull
|
||||||
|
ssh://hg@bitbucket.org/tyrelsouza/torchtester
|
0
.hg/undo.dirstate
Normal file
0
.hg/undo.dirstate
Normal file
BIN
Program Files/TorchTester/blank.png
Normal file
BIN
Program Files/TorchTester/blank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 176 B |
BIN
Program Files/TorchTester/green.png
Normal file
BIN
Program Files/TorchTester/green.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
BIN
Program Files/TorchTester/red.png
Normal file
BIN
Program Files/TorchTester/red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
19
README.txt
Normal file
19
README.txt
Normal file
@ -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!
|
1571
TorchTester.fbp
Normal file
1571
TorchTester.fbp
Normal file
File diff suppressed because it is too large
Load Diff
18
TorchTester.sln
Normal file
18
TorchTester.sln
Normal file
@ -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
|
BIN
TorchTester.suo
Normal file
BIN
TorchTester.suo
Normal file
Binary file not shown.
140
TorchTester/Program.py
Normal file
140
TorchTester/Program.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
"""
|
||||||
|
Author: Tyrel Souza
|
||||||
|
<tyrel@tyrelsouza.com>
|
||||||
|
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)
|
||||||
|
|
BIN
TorchTester/TorchTester.ico
Normal file
BIN
TorchTester/TorchTester.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 318 B |
32
TorchTester/TorchTester.pyproj
Normal file
32
TorchTester/TorchTester.pyproj
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{a172b229-11f0-4265-9205-fa5a8ec52471}</ProjectGuid>
|
||||||
|
<ProjectHome>.</ProjectHome>
|
||||||
|
<StartupFile>Program.py</StartupFile>
|
||||||
|
<SearchPath>
|
||||||
|
</SearchPath>
|
||||||
|
<WorkingDirectory>.</WorkingDirectory>
|
||||||
|
<AssemblyName>TorchTester</AssemblyName>
|
||||||
|
<Name>TorchTester</Name>
|
||||||
|
<RootNamespace>TorchTester</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="logic.py" />
|
||||||
|
<Compile Include="frmMain.py" />
|
||||||
|
<Compile Include="initialization.py" />
|
||||||
|
<Compile Include="wxImages.py" />
|
||||||
|
<Compile Include="scanports.py" />
|
||||||
|
<Compile Include="Program.py" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
127
TorchTester/TorchTester.pyw
Normal file
127
TorchTester/TorchTester.pyw
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
"""
|
||||||
|
Author: Tyrel Souza
|
||||||
|
<tyrel@tyrelsouza.com>
|
||||||
|
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)
|
||||||
|
|
251
TorchTester/frmMain.py
Normal file
251
TorchTester/frmMain.py
Normal file
@ -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)
|
39
TorchTester/initialization.py
Normal file
39
TorchTester/initialization.py
Normal file
@ -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))
|
248
TorchTester/logic.py
Normal file
248
TorchTester/logic.py
Normal file
@ -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)
|
43
TorchTester/scanports.py
Normal file
43
TorchTester/scanports.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
"""\
|
||||||
|
Scan for serial ports.
|
||||||
|
|
||||||
|
Part of pySerial (http://pyserial.sf.net)
|
||||||
|
(C) 2002-2003 <cliechti@gmx.net>
|
||||||
|
|
||||||
|
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*')
|
||||||
|
|
221
TorchTester/wxImages.py
Normal file
221
TorchTester/wxImages.py
Normal file
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user