t push -u origin master
This commit is contained in:
commit
1b565ebb07
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,2 @@
|
|||
f955b00a6181dc5bdf0112fcaef09591a748fadd 25
|
||||
f955b00a6181dc5bdf0112fcaef09591a748fadd o default
|
|
@ -0,0 +1 @@
|
|||
default
|
Binary file not shown.
Binary file not shown.
|
@ -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>
|
|
@ -0,0 +1,4 @@
|
|||
dotencode
|
||||
fncache
|
||||
revlogv1
|
||||
store
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,3 @@
|
|||
0
|
||||
pull
|
||||
ssh://hg@bitbucket.org/tyrelsouza/torchtester
|
Binary file not shown.
After Width: | Height: | Size: 176 B |
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
|
@ -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!
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
Binary file not shown.
|
@ -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)
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 318 B |
|
@ -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>
|
|
@ -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)
|
||||
|
|
@ -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)
|
|
@ -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))
|
|
@ -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)
|
|
@ -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*')
|
||||
|
|
@ -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