diff options
| author | Donald Delmar Davis <don@suspectdevices.com> | 2012-10-16 17:04:16 -0700 |
|---|---|---|
| committer | Donald Delmar Davis <don@suspectdevices.com> | 2012-10-16 17:04:16 -0700 |
| commit | cef652ac1861410a885f8398f9c35d286f4f8a8d (patch) | |
| tree | b18824751aa30225a99f71cc5e0ee646c7f5ea5d /dumblogger/utilities | |
| parent | d60d28c60d450ad797308b4883ead3d57905146a (diff) | |
plodding right along
Diffstat (limited to 'dumblogger/utilities')
| -rw-r--r-- | dumblogger/utilities/AMAv2.py | 360 | ||||
| -rw-r--r-- | dumblogger/utilities/ConsoleApp.py | 273 | ||||
| -rw-r--r-- | dumblogger/utilities/confignetwork.py | 306 | ||||
| -rw-r--r-- | dumblogger/utilities/console-1.icns | bin | 0 -> 107513 bytes | |||
| -rw-r--r-- | dumblogger/utilities/console.icns | bin | 0 -> 107513 bytes | |||
| -rw-r--r-- | dumblogger/utilities/developer_32x32x32.png | bin | 0 -> 1728 bytes | |||
| -rw-r--r-- | dumblogger/utilities/graph.icns | bin | 0 -> 34995 bytes | |||
| -rw-r--r-- | dumblogger/utilities/icons.py | 83 | ||||
| -rw-r--r-- | dumblogger/utilities/setup.py | 31 | ||||
| -rw-r--r-- | dumblogger/utilities/software_update.icns | bin | 0 -> 41957 bytes | |||
| -rw-r--r-- | dumblogger/utilities/software_update.ico | bin | 0 -> 67646 bytes | |||
| -rw-r--r-- | dumblogger/utilities/software_update_32x32x32.png | bin | 0 -> 1945 bytes |
12 files changed, 1053 insertions, 0 deletions
diff --git a/dumblogger/utilities/AMAv2.py b/dumblogger/utilities/AMAv2.py new file mode 100644 index 0000000..9b6f7ea --- /dev/null +++ b/dumblogger/utilities/AMAv2.py @@ -0,0 +1,360 @@ +#!/usr/bin/python
+"""
+*-----------------------------------------------------------------------AMAv2.py
+* XtractWork
+*
+* Created by Donald D Davis on 9/11/12.
+* Copyright 2012 Suspect Device, for xtractSolutions . All rights reserved.
+*
+* Python Class to simplify interaction between the monitor on the AMA and
+* programs to monitor and control it, the class uses a dispatch table to
+* define the actions. The open command can be used to identify both the ama
+* port and the logger and to identify an ama that is attached through the logger.
+*
+* the class/behaviour model should be used to create the next gen of bom code.
+*
+* you can use this to identify the logger or you can superclass the AMAv2
+* to create at BOM5k class. (I dont know which is more appropriate yet)
+*
+* The test case for the class below demonstrates how to attach the a
+* function to the dispatch table using the log keyword to push data to
+* the google app.
+*
+*
+"""
+
+import re
+import string
+import datetime
+import serial
+import os
+import os.path
+import shutil
+import platform
+import sys
+import time
+import re
+
+def list_serial_ports():
+ def full_port_name(portname):
+ """ Given a port-name (of the form COM7, COM12, CNCA0, etc.) returns a full
+ name suitable for opening with the Serial class.
+ http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/
+ """
+ m = re.match('^COM(\d+)$', portname)
+ if m and int(m.group(1)) < 10:
+ return portname
+ return '\\\\.\\' + portname
+
+ plat_sys = platform.system()
+ plat_bits = platform.architecture()[0]
+
+ if plat_sys == 'Windows':
+ import _winreg as reg
+ p = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
+ k = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, p)
+ possible_paths = []
+ i = 0
+ while True:
+ try:
+ possible_paths.append(full_port_name(reg.EnumValue(k, i)[1]))
+ i += 1
+ except WindowsError:
+ break
+ else:
+ if plat_sys == 'Linux':
+ file_prefix='ttyACM'
+ elif plat_sys == 'Darwin':
+ file_prefix='cu.usbmodem'
+
+ possible_paths = [os.path.join('/dev', x) for x in os.listdir('/dev') \
+ if x.startswith(file_prefix)]
+ if len(possible_paths) == 0:
+ return None
+ return possible_paths
+
+
+#from SDserialutilities import list_serial_ports
+
+class AMAv2:
+
+ def __init__(self, portname=None, baudrate=9600, logger_only=False):
+ self.ser=None
+ self.attached=False
+ self.lastcontact=None
+ self.lastTimestamp=None
+ self.command_state=-1
+ self.acknowleged=False
+ self.dispatch_table={
+ 'SSN':self.ssn,'HWV':self.hwv,'SWV':self.swv,'LOG':self.log,
+ 'LSV':self.lsv,'ACK':self.ack,'DVP':self.dvp,'CMD':self.cmd,
+ 'DBG':self.dbg,'ALT':self.alt,'WRN':self.alt,'STC':self.alt
+ }
+ self.status={
+ 'TS1':None,'TS2':None,'TS3':None,'TS4':None,'TS5':None,
+ 'FAP':None,'FAN':None,'CHL':None,'PWR':None,'THR':None,
+ 'EC1':None,'EC2':None,'EC2':None
+ }
+
+ for var in self.status.keys():
+ self.dispatch_table[var]=self.update_state_variable
+
+ #for var in ['FAN','CHL']:
+ # self.dispatch_table[var]=self.update_state_integer
+ #for var in ['TS1','TS2','TS3','TS4','TS5']:
+ # self.dispatch_table[var]=self.update_state_float
+
+ self.open(portname,baudrate,logger_only)
+
+
+ def yank_timestamp(self,value):
+ if value is None:
+ return None
+ try:
+
+ ll=value.split(',',2)
+ #print value,"->",ll,len(ll)
+ if len(ll) == 1:
+ self.lastcontact=datetime.datetime.utcnow()
+ return ll[0]
+ else:
+ self.lastcontact=datetime.datetime.utcnow()
+ self.lastTimestamp=ll[0]
+ return ll[1]
+ except Exception as e:
+ print "error in yank timestamp:", str(e)
+ return None
+
+ def update_state_variable(self,key,verb,value):
+ self.status[key]=self.yank_timestamp(value)
+ #should maybe flag the update somewhere
+ #may want ot return something.
+
+ def set_dispatch_function(self,key,d_fun):
+ #should check key value and callable here....
+ self_dispatch_table[key]=d_fun
+
+ def log(self,key='LOG',verb=':',value=None):
+ if value is not None:
+ print "LOG:"+value.rstrip('\r\n')
+ return value
+
+
+ def alt(self,key='ALT',verb='?',value=None):
+ if value is not None:
+ print key+":"+value.rstrip('\r\n')
+ return value
+
+ def ssn(self,key='SSN',verb='?',value=None):
+ if (value is not None):
+ ssn=self.yank_timestamp(value).rstrip('\r\n')
+ if ( len(ssn)>9 and all(char in string.hexdigits for char in ssn) ):
+ self.device_ssn_string=ssn
+ else:
+ self.sendCMD("SSN?") #we got garbage ask again
+ return self.device_ssn_string
+
+ def hwv(self,key='HWV',verb='?',value=None):
+ if value is not None:
+ self.device_hwv_string=self.yank_timestamp(value)
+ return self.device_hwv_string
+
+ def swv(self,key='SWV',verb='?',value=None):
+ if value is not None:
+ self.device_swv_string=self.yank_timestamp(value)
+ return self.device_swv_string
+
+ def lsv(self,key='LSV',verb=':',value=None):
+ if value is not None:
+ print "LSV",
+ self.logger_swv_string=self.yank_timestamp(value)
+ print self.logger_swv_string
+ return self.logger_swv_string
+
+ def ack(self,key='ACK',verb='?',value=None):
+ if value is not None:
+ self.yank_timestamp(value)
+ self.acknowleged=True
+ return self.acknowleged
+
+ def cmd(self,key='CMD',verb='?',value=None):
+ if value is not None:
+ self.command_state= "ON" in self.yank_timestamp(value)
+ return self.command_state
+
+ def dvp(self,key='DVP',verb='?',value=None):
+ if value is not None:
+ self.device_on_logger = not "NOT" in self.yank_timestamp(value)
+ return self.device_on_logger
+
+ def dbg(self,key='DBG',verb=':',value=None):
+ if value is not None:
+ print key+":"+value
+ #return something probably
+
+ def sendCMD(self,cmd=None):
+ if cmd is not None and self.ser is not None:
+ self.ser.write(cmd+'\r\n')
+ #return something probably
+
+ def nop(self,key='NOP',verb=':',value=None):
+ print key,"DBG:("+key+")not implimented!!!"
+
+
+ def open(self,portname,baudrate,logger_only=False,printDebug=True):
+ attempts=2
+ line=''
+ self.version_string=None
+ self.device_ssn_string=None
+ self.device_swv_string=None
+ self.device_dbg_level=None
+ self.device_log_level=None
+ self.logger_swv_string=None
+ self.device_on_logger=False
+ self.portname=None
+ self.logger_portname=None
+ self.lastconact=None
+ self.initialContact=None
+ self.ser=None
+ while attempts and self.portname is None:
+ ports=list_serial_ports()
+ if ports is None:
+ break
+ else:
+ for port in ports:
+ try:
+ self.initialContact=[]
+ ser=serial.Serial(port,9600,timeout=1)#,dsrdtr=True,rtscts=True)
+ if not ser.isOpen:
+ continue
+ ser.flushInput()
+ time.sleep(.1)
+ try_no=1
+ while not ser.inWaiting():
+ time.sleep(.15)
+ try_no=try_no+1
+ if try_no > 15:
+ break
+
+ try_no=1
+ ser.write('SYN!\r\nLSV?\r\nDVP?\r\nDLG!0\r\nSSN?\r\nSWV?\r\nHWV?\r\n')
+ while not ser.inWaiting():
+ time.sleep(.15)
+ try_no=try_no+1
+ if try_no > 15:
+ break
+
+ while ser.inWaiting():
+ line=unicode(ser.readline(100).rstrip('\r\n'), errors='ignore')
+ line=line.encode('ascii','ignore')
+ if len(line.split('\r'))>1:
+ line=line.split('\r')[1] # if input echo is on strip input.
+ #print '\r\n'+repr(line)+'\r\n'
+ if len(line) > 3 and line[3] == ':' :
+ self.dispatch(line)
+ else:
+ print "DBG:GARBAGE >>"+line+"<<"
+ #check stream for rev 1 hardware
+ self.initialContact.append(line)
+ #time.sleep(.1)
+ if not logger_only:
+ time.sleep(.35)
+
+ except Exception as e:
+ print line
+ print "Error in open :", str(e)
+
+ if self.logger_swv_string is not None:
+ print "DBG:Found a Logger : version =", self.logger_swv_string
+ self.logger_portname=port
+ if not self.device_on_logger:
+ self.device_swv_string=None
+ if logger_only:
+ self.portname=port
+ self.ser=ser
+
+ if self.device_swv_string is not None:
+ print "DBG:Found an AMA : version =", self.device_swv_string
+ print "DBG:SSN =", self.device_ssn_string
+ self.portname=port
+ self.ser=ser
+ break
+ if self.portname is None:
+ ser.close()
+ attempts=attempts-1
+ self.attached = (self.ser is not None)
+ print ":", self.attached, self.logger_swv_string,self.ser
+
+ def dispatch(self,buffer):
+ if buffer is None:
+ print "DBG:short read"
+ return
+ if (len(buffer) < 4) or buffer=='':
+ print "DBG:"+repr(buffer.rstrip('\r\n'))
+ return
+ key=buffer[0:3]
+ verb=buffer[3]
+ if len(buffer) > 4:
+ value=buffer[4:].rstrip('\r\n')
+ else:
+ value=''
+ self.dispatch_table.get(key,self.nop)(key,verb,value)
+"""
+*----------------------------------------------------------------------test code
+*
+*
+"""
+
+
+if __name__ == "__main__":
+
+
+ import httplib, urllib
+
+ def log_to_app(key,verb=':',value=None):
+ if value is not None and device.device_ssn_string is not None :
+ try:
+ print "LOG:(" + device.device_ssn_string + ")" + value
+ ssn=device.device_ssn_string
+ (timestamp,ambient,chiller1,chiller2,air1,air2,chiller,
+ fan,state) = value.split(',')
+ #print "SANITY CHECK", ssn, timestamp, ambient
+ params = urllib.urlencode({#'ssn': ssn,
+ 'timestamp':timestamp,
+ 'ts1': ambient,
+ 'ts2': chiller1,'ts3': chiller2,
+ 'ts4': air1, 'ts5': air2,
+ 'chiller': chiller,
+ 'fan': fan,
+ 'state': state
+
+ })
+ headers = {"Content-type": "application/x-www-form-urlencoded",
+ "Accept": "text/plain"}
+ conn = httplib.HTTPConnection("patch-bay.appspot.com")
+ # need to deal with bogus ssn value
+ conn.request("POST", "/log?ssn="+ssn, params, headers)
+ response = conn.getresponse()
+ print "DBG:"+str(response.status),response.reason,
+ data = response.read()
+ print data.rstrip('\r\n')
+ conn.close()
+ except Exception as e:
+ print "DBG:NETWORK?"+str(e)
+
+ def test_stc (key,verb,value):
+ print key,verb,value,device.device_ssn_string
+
+
+ device=AMAv2(logger_only=True)
+ if device.ser is None:
+ print "FOUND NO AMA DEVICE"
+ exit()
+ device.dispatch_table['LOG']=log_to_app
+ while True:
+ if device.ser.inWaiting():
+ line=device.ser.readline(100).rstrip('\r\n')
+ line=line.encode('ascii', 'ignore')
+
+ device.dispatch(line)
+
diff --git a/dumblogger/utilities/ConsoleApp.py b/dumblogger/utilities/ConsoleApp.py new file mode 100644 index 0000000..3993f6b --- /dev/null +++ b/dumblogger/utilities/ConsoleApp.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python + +import wx +import subprocess +import datetime +import time +import os +from wx.lib.embeddedimage import PyEmbeddedImage + +from AMAv2 import AMAv2 +import icons +#self.button1 = wx.BitmapButton(self.panel1, id=-1, bitmap=image1, + +libmaple_directory=os.path.dirname(os.path.realpath(__file__)) + os.sep + '../../libmaple/' +program_code_directory='../programs/dumblogger' +my_dir=os.path.dirname(os.path.realpath(__file__)) + + +[wxID_CONSOLE_FRAME, wxID_CONSOLE_FRAMECMD, wxID_CONSOLE_FRAMEOUTPUT, wxID_CONSOLE_FRAMEREBUILD, + wxID_CONSOLE_FRAMERESET, wxID_CONSOLE_FRAMESTATUSBAR1, +] = [wx.NewId() for _init_ctrls in range(6)] + +class ConsoleFrame(wx.Frame): + def _init_coll_boxSizer1_Items(self, parent): + # generated method, don't edit + + parent.AddSizer(self.boxSizer2, 0, border=0, flag=wx.EXPAND) + parent.AddSizer(self.boxSizer3, 1, border=0, flag=wx.EXPAND) + parent.AddWindow(self.statusBar1, 0, border=0, flag=0) + + def _init_coll_boxSizer2_Items(self,parent): + parent.AddWindow(self.RESET, 0, border=0, flag=0) + parent.AddWindow(self.REBUILD, 0, border=0, flag=0) + + def _init_coll_boxSizer3_Items(self, parent): + parent.AddWindow(self.OUTPUT, 1, border=0, flag=wx.EXPAND) + parent.AddWindow(self.CMD, 0, border=0, flag=wx.EXPAND) + + def _init_sizers(self): + # generated method, don't edit + self.boxSizer1 = wx.BoxSizer(orient=wx.VERTICAL) + + self.boxSizer2 = wx.BoxSizer(orient=wx.HORIZONTAL) + + self.boxSizer3 = wx.BoxSizer(orient=wx.VERTICAL) + + self._init_coll_boxSizer1_Items(self.boxSizer1) + self._init_coll_boxSizer2_Items(self.boxSizer2) + self._init_coll_boxSizer3_Items(self.boxSizer3) + + self.SetSizer(self.boxSizer1) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Frame.__init__(self, id=wxID_CONSOLE_FRAME, name='', parent=prnt, + pos=wx.Point(265, 195), size=wx.Size(838, 526), + style=wx.DEFAULT_FRAME_STYLE, title='BOM5k Console') + self.SetClientSize(wx.Size(838, 504)) + + self.CMD = wx.TextCtrl(id=wxID_CONSOLE_FRAMECMD, name=u'CMD', parent=self, + pos=wx.Point(0, 62), size=wx.Size(100, 22), style=wx.TE_PROCESS_ENTER|wx.PROCESS_ENTER, value=u'>') + self.CMD.Bind(wx.EVT_TEXT_ENTER, self.OnCMDText, id=wxID_CONSOLE_FRAMECMD) + self.CMD.Bind(wx.EVT_KILL_FOCUS, self.OnCMDKillFocus) + + self.OUTPUT = wx.TextCtrl(id=wxID_CONSOLE_FRAMEOUTPUT, name=u'OUTPUT', + parent=self, pos=wx.Point(0, 40), size=wx.Size(100, 22), style=wx.TE_MULTILINE, + value=u'') + self.OUTPUT.SetEditable(False) + #self.OUTPUT.SetAutoLayout(True) + self.OUTPUT.Enable(False) + + self.REBUILD = wx.Button(id=wxID_CONSOLE_FRAMEREBUILD, label=u'REBUILD', + name=u'REBUILD', parent=self, pos=wx.Point(0, 20), + size=wx.Size(84, 20), style=0) + self.REBUILD.Bind(wx.EVT_BUTTON, self.OnREBUILDButton, + id=wxID_CONSOLE_FRAMEREBUILD) + + self.RESET = wx.Button(id=wxID_CONSOLE_FRAMERESET, label=u'RESET', + name=u'RESET', parent=self, pos=wx.Point(0, 0), size=wx.Size(84, + 20), style=0) + + self.statusBar1 = wx.StatusBar(id=wxID_CONSOLE_FRAMESTATUSBAR1, + name='statusBar1', parent=self, style=0) + self.statusBar1.SetFieldsCount(4) + self.statusBar1.SetStatusWidths([-1,-1,-1,-1]) + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + MenuBar = wx.MenuBar() + + FileMenu = wx.Menu() + + item = FileMenu.Append(wx.ID_EXIT, text = "&Exit") + self.Bind(wx.EVT_MENU, self.OnQuit, item) + + item = FileMenu.Append(wx.ID_ANY, text = "&Open Source Code") + self.Bind(wx.EVT_MENU, self.OnOpen, item) + + item = FileMenu.Append(wx.ID_PREFERENCES, text = "&Preferences") + self.Bind(wx.EVT_MENU, self.OnPrefs, item) + + MenuBar.Append(FileMenu, "&File") + + HelpMenu = wx.Menu() + + item = HelpMenu.Append(wx.ID_HELP, "Test &Help", + "Help for this simple test") + self.Bind(wx.EVT_MENU, self.OnHelp, item) + + ## this gets put in the App menu on OS-X + item = HelpMenu.Append(wx.ID_ABOUT, "&About", + "More information About this program") + self.Bind(wx.EVT_MENU, self.OnAbout, item) + MenuBar.Append(HelpMenu, "&Help") + + self.SetMenuBar(MenuBar) + + self.device_was_already_attached=False + self.device=AMAv2(logger_only=True) + self.serialTimer = wx.Timer(self,-1) + self.Bind(wx.EVT_TIMER, self.processSerial, self.serialTimer) + self.serialTimer.Start(750) + + + + + + def OnQuit(self,Event): + self.Destroy() + + def OnAbout(self, event): + dlg = wx.MessageDialog(self, "This is a small program to test\n" + "the use of menus on Mac, etc.\n", + "About Me", wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnHelp(self, event): + dlg = wx.MessageDialog(self, "This would be help\n" + "If there was any\n", + "Test Help", wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + def OnOpen(self, event): + dialog = wx.DirDialog(None, "Directory containing code :", style=wx.DD_DIR_MUST_EXIST ) + if dialog.ShowModal() == wx.ID_OK: + #libmaple_directory = dialog.GetPath() + program_code_directory=dialog.GetPath() + self.OnREBUILDButton(event) + dialog.Destroy() + +# dlg = wx.MessageDialog(self, "This would be an open Dialog\n" +# "If there was anything to open\n", +# "Open File", wx.OK | wx.ICON_INFORMATION) +# dlg.ShowModal() +# dlg.Destroy() + + def OnPrefs(self, event): + dlg = wx.MessageDialog(self, "This would be an preferences Dialog\n" + "If there were any preferences to set.\n", + "Preferences", wx.OK | wx.ICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + + + + def OnREBUILDButton(self, event): + self.statusBar1.SetStatusText("...Uploading...",1) + self.OUTPUT.AppendText('\n---------------------- UPLOAD -------------------\n') + if self.device.ser is not None: + self.device.ser.close() + self.device.attached=False + try: + self.OUTPUT.AppendText(subprocess.check_output("make install", + env={'BOARD': 'maple_mini','USER_MODULES': program_code_directory, + 'PATH': '/usr/local/arm-none-eabi/bin/:/usr/local/bin/:/usr/bin:/bin/:$PATH'}, + #stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=True, + cwd=libmaple_directory)) + self.OUTPUT.AppendText('\n------------------- SUCCESS ------------------\n') + + except CalledProcessError as e: + self.OUTPUT.AppendText(e.cmd +"Returned "+str(e.returncode)) + self.OUTPUT.AppendText(e.output) + self.OUTPUT.AppendText('\n-------------------- FAIL --------------------\n') + + time.sleep(1) + self.OnReconnect() + #self.device.attached=True # should be handled by ama class + if event is not None: + event.Skip() + + def OnCMDText(self, event): + comm=self.CMD.GetValue().rstrip('\r\n') + self.CMD.SetValue('') + self.statusBar1.SetStatusText(">>"+comm,0) + if self.device.attached: + self.device.ser.write(str(comm)+'\r\n') + event.Skip() + + def OnReconnect(self, event=None): + self.device.attached=False + if self.device.ser is not None: + self.device.ser.close() + self.statusBar1.SetStatusText("...Searching...",1) + self.device.open(self.device.portname,9600,logger_only=True) + print "?",self.device.attached, self.device.logger_swv_string, self.device.ser + if self.device.ser is not None and self.device.ser.isOpen(): + self.statusBar1.SetStatusText(self.device.logger_swv_string,1) + if event is not None: + event.Skip() + + + def OnCMDKillFocus(self, event): + event.Skip() + + + def processSerial(self,event=None): + if self.device.attached: + if not self.device_was_already_attached: + self.statusBar1.SetStatusText(self.device.logger_swv_string,1) + try: + while self.device.ser.inWaiting(): + line=unicode(self.device.ser.readline(100).rstrip('\r\n'),errors='ignore') + line=line.encode('ascii','replace') + self.OUTPUT.AppendText(line+'\n') + self.device.dispatch(line) + except IOError as e: + self.device.attached=False + else: + self.OnReconnect() + self.device_was_already_attached=self.device.attached + if event is not None: + event.Skip() + +# stubs for mac events... + + + def MacOpenFile(self, filename): + """Called for files droped on dock icon, or opened via finders context menu""" + print filename + print "%s dropped on app"%(filename) #code to load filename goes here. + program_code_directory = os.path.dirname(os.path.realpath(filename)) + self.OnREBUILDButton() + + def MacReopenApp(self): + """Called when the doc icon is clicked, and ???""" + self.BringWindowToFront() + + def MacNewFile(self): + pass + + def MacPrintFile(self, file_path): + pass + + +class ConsoleApp(wx.App): + def OnInit(self): + self.main = ConsoleFrame(None) + self.main.Show() + self.SetTopWindow(self.main) + return True + +def main(): + application = ConsoleApp(0) + application.MainLoop() + +if __name__ == '__main__': + main() diff --git a/dumblogger/utilities/confignetwork.py b/dumblogger/utilities/confignetwork.py new file mode 100644 index 0000000..3123ab2 --- /dev/null +++ b/dumblogger/utilities/confignetwork.py @@ -0,0 +1,306 @@ +import wx +import wx.lib.buttons as buttons + +import os +import sys + +try: + dirName = os.path.dirname(os.path.abspath(__file__)) +except: + dirName = os.path.dirname(os.path.abspath(sys.argv[0])) + +sys.path.append(os.path.split(dirName)[0]) + +try: + from agw import pycollapsiblepane as PCP +except ImportError: # if it's not there locally, try the wxPython lib. + import wx.lib.agw.pycollapsiblepane as PCP + +import images + +btnlbl1 = "call Expand(True)" +btnlbl2 = "call Expand(False)" + +choices = ["wx.Button", + "GenButton", + "GenBitmapButton", + "GenBitmapTextButton", + "ThemedGenButton", + "ThemedGenBitmapTextButton"] + +gtkChoices = ["3, 6", + "4, 8", + "5, 10"] + +styles = ["CP_NO_TLW_RESIZE", + "CP_LINE_ABOVE", + "CP_USE_STATICBOX", + "CP_GTK_EXPANDER"] + + +class PyCollapsiblePaneDemo(wx.Panel): + + def __init__(self, parent, log): + + wx.Panel.__init__(self, parent) + + self.log = log + + self.label1 = "Click here to show pane" + self.label2 = "Click here to hide pane" + + title = wx.StaticText(self, label="PyCollapsiblePane") + title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD)) + title.SetForegroundColour("blue") + + self.cpStyle = wx.CP_NO_TLW_RESIZE + self.cp = cp = PCP.PyCollapsiblePane(self, label=self.label1, + agwStyle=self.cpStyle) + self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged, cp) + self.MakePaneContent(cp.GetPane()) + + self.btnRB = radioBox = wx.RadioBox(self, -1, "Button Types", + choices=choices, style=wx.RA_SPECIFY_ROWS) + self.static1 = wx.StaticText(self, -1, "Collapsed Button Text:") + self.static2 = wx.StaticText(self, -1, "Expanded Button Text:") + + self.buttonText1 = wx.TextCtrl(self, -1, self.label1) + self.buttonText2 = wx.TextCtrl(self, -1, self.label2) + self.updateButton = wx.Button(self, -1, "Update!") + + sbox = wx.StaticBox(self, -1, 'Styles') + sboxsizer = wx.StaticBoxSizer(sbox, wx.VERTICAL) + self.styleCBs = list() + for styleName in styles: + cb = wx.CheckBox(self, -1, styleName) + if styleName == "CP_NO_TLW_RESIZE": + cb.SetValue(True) + cb.Disable() + cb.Bind(wx.EVT_CHECKBOX, self.OnStyleChoice) + self.styleCBs.append(cb) + sboxsizer.Add(cb, 0, wx.ALL, 4) + + self.gtkText = wx.StaticText(self, -1, "Expander Size") + self.gtkChoice = wx.ComboBox(self, -1, choices=gtkChoices) + self.gtkChoice.SetSelection(0) + + self.gtkText.Enable(False) + self.gtkChoice.Enable(False) + + sizer = wx.BoxSizer(wx.VERTICAL) + radioSizer = wx.BoxSizer(wx.HORIZONTAL) + dummySizer = wx.BoxSizer(wx.VERTICAL) + + dummySizer.Add(self.gtkText, 0, wx.EXPAND|wx.BOTTOM, 2) + dummySizer.Add(self.gtkChoice, 0, wx.EXPAND) + + radioSizer.Add(radioBox, 0, wx.EXPAND) + radioSizer.Add(sboxsizer, 0, wx.EXPAND|wx.LEFT, 10) + radioSizer.Add(dummySizer, 0, wx.ALIGN_BOTTOM|wx.LEFT, 10) + + self.SetSizer(sizer) + sizer.Add((0, 10)) + sizer.Add(title, 0, wx.LEFT|wx.RIGHT, 25) + sizer.Add((0, 10)) + sizer.Add(radioSizer, 0, wx.LEFT, 25) + + sizer.Add((0, 10)) + subSizer = wx.FlexGridSizer(2, 3, 5, 5) + subSizer.Add(self.static1, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) + subSizer.Add(self.buttonText1, 0, wx.EXPAND) + subSizer.Add((0, 0)) + subSizer.Add(self.static2, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) + subSizer.Add(self.buttonText2, 0, wx.EXPAND) + subSizer.Add(self.updateButton, 0, wx.LEFT|wx.RIGHT, 10) + + subSizer.AddGrowableCol(1) + + sizer.Add(subSizer, 0, wx.EXPAND|wx.LEFT, 20) + sizer.Add((0, 15)) + sizer.Add(cp, 0, wx.RIGHT|wx.LEFT|wx.EXPAND, 20) + + self.btn = wx.Button(self, label=btnlbl1) + sizer.Add(self.btn, 0, wx.ALL, 25) + + self.Bind(wx.EVT_BUTTON, self.OnToggle, self.btn) + self.Bind(wx.EVT_BUTTON, self.OnUpdate, self.updateButton) + self.Bind(wx.EVT_RADIOBOX, self.OnButtonChoice) + self.Bind(wx.EVT_COMBOBOX, self.OnUserChoice, self.gtkChoice) + + + def OnToggle(self, event): + + self.cp.Collapse(self.cp.IsExpanded()) + self.OnPaneChanged() + + + def OnUpdate(self, event): + + self.label1 = self.buttonText1.GetValue() + self.label2 = self.buttonText2.GetValue() + + self.OnPaneChanged(None) + + + def OnStyleChoice(self, evt): + style = 0 + for cb in self.styleCBs: + if cb.IsChecked(): + style |= getattr(wx, cb.GetLabel(), 0) + + self.cpStyle = style + self.Rebuild() + + + def OnButtonChoice(self, event): + + #self.gtkText.Enable(selection == 4) + #self.gtkChoice.Enable(selection == 4) + + self.Rebuild() + + + def MakeButton(self): + + if self.cpStyle & wx.CP_GTK_EXPANDER: + return None + + selection = self.btnRB.GetSelection() + + if selection == 0: # standard wx.Button + btn = wx.Button(self.cp, -1, self.label1) + elif selection == 1: # buttons.GenButton + btn = buttons.GenButton(self.cp, -1, self.label1) + elif selection == 2: # buttons.GenBitmapButton + bmp = images.Smiles.GetBitmap() + btn = buttons.GenBitmapButton(self.cp, -1, bmp) + elif selection == 3: # buttons.GenBitmapTextButton + bmp = images.Mondrian.GetBitmap() + btn = buttons.GenBitmapTextButton(self.cp, -1, bmp, self.label1) + elif selection == 4: # buttons.ThemedGenButton + btn = buttons.ThemedGenButton(self.cp, -1, self.label1) + elif selection == 5: # buttons.ThemedGenBitmapTextButton + bmp = images.Mondrian.GetBitmap() + btn = buttons.ThemedGenBitmapTextButton(self.cp, -1, bmp, self.label1) + + return btn + + + def Rebuild(self): + + isExpanded = self.cp.IsExpanded() + self.Freeze() + cp = PCP.PyCollapsiblePane(self, label=self.label1, agwStyle=self.cpStyle) + cp.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged) + self.MakePaneContent(cp.GetPane()) + cp.SetExpanderDimensions(*self.GetUserSize()) + self.GetSizer().Replace(self.cp, cp) + self.cp.Destroy() + self.cp = cp + + btn = self.MakeButton() + if btn: + self.cp.SetButton(btn) + self.gtkText.Enable(btn is None) + self.gtkChoice.Enable(btn is None) + self.btnRB.Enable(btn is not None) + + if isExpanded: + self.cp.Expand() + self.Thaw() + + self.OnPaneChanged(None) + self.Layout() + + + def OnPaneChanged(self, event=None): + + if event: + self.log.write('wx.EVT_COLLAPSIBLEPANE_CHANGED: %s\n' % event.Collapsed) + + # redo the layout + self.Layout() + + # and also change the labels + if self.cp.IsExpanded(): + self.cp.SetLabel(self.label2) + self.btn.SetLabel(btnlbl2) + else: + self.cp.SetLabel(self.label1) + self.btn.SetLabel(btnlbl1) + + self.btn.SetInitialSize() + + + def OnUserChoice(self, event): + + self.cp.SetExpanderDimensions(*self.GetUserSize(event.GetSelection())) + + + def GetUserSize(self, selection=None): + + if selection is None: + selection = self.gtkChoice.GetSelection() + + choice = gtkChoices[selection] + width, height = choice.split(",") + + return int(width), int(height) + + + def MakePaneContent(self, pane): + '''Just make a few controls to put on the collapsible pane''' + + nameLbl = wx.StaticText(pane, -1, "SSID:") + name = wx.TextCtrl(pane, -1, ""); + + addrLbl = wx.StaticText(pane, -1, "PASSWORD:") + addr1 = wx.TextCtrl(pane, -1, ""); + addr2 = wx.TextCtrl(pane, -1, ""); + + cstLbl = wx.StaticText(pane, -1, "SITE IP,SITE FEED, HRRM:") + city = wx.TextCtrl(pane, -1, "", size=(150,-1)); + state = wx.TextCtrl(pane, -1, "", size=(50,-1)); + zip = wx.TextCtrl(pane, -1, "", size=(70,-1)); + + addrSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5) + addrSizer.AddGrowableCol(1) + addrSizer.Add(nameLbl, 0, + wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) + addrSizer.Add(name, 0, wx.EXPAND) + addrSizer.Add(addrLbl, 0, + wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) + addrSizer.Add(addr1, 0, wx.EXPAND) + addrSizer.Add((5,5)) + addrSizer.Add(addr2, 0, wx.EXPAND) + + addrSizer.Add(cstLbl, 0, + wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL) + + cstSizer = wx.BoxSizer(wx.HORIZONTAL) + cstSizer.Add(city, 1) + cstSizer.Add(state, 0, wx.LEFT|wx.RIGHT, 5) + cstSizer.Add(zip) + addrSizer.Add(cstSizer, 0, wx.EXPAND) + + border = wx.BoxSizer() + border.Add(addrSizer, 1, wx.EXPAND|wx.ALL, 5) + pane.SetSizer(border) + + +#---------------------------------------------------------------------- + +def runTest(frame, nb, log): + win = PyCollapsiblePaneDemo(nb, log) + return win + +#---------------------------------------------------------------------- + +overview = PCP.__doc__ + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) + + diff --git a/dumblogger/utilities/console-1.icns b/dumblogger/utilities/console-1.icns Binary files differnew file mode 100644 index 0000000..0328430 --- /dev/null +++ b/dumblogger/utilities/console-1.icns diff --git a/dumblogger/utilities/console.icns b/dumblogger/utilities/console.icns Binary files differnew file mode 100644 index 0000000..0328430 --- /dev/null +++ b/dumblogger/utilities/console.icns diff --git a/dumblogger/utilities/developer_32x32x32.png b/dumblogger/utilities/developer_32x32x32.png Binary files differnew file mode 100644 index 0000000..947dc14 --- /dev/null +++ b/dumblogger/utilities/developer_32x32x32.png diff --git a/dumblogger/utilities/graph.icns b/dumblogger/utilities/graph.icns Binary files differnew file mode 100644 index 0000000..2e8df9c --- /dev/null +++ b/dumblogger/utilities/graph.icns diff --git a/dumblogger/utilities/icons.py b/dumblogger/utilities/icons.py new file mode 100644 index 0000000..346616d --- /dev/null +++ b/dumblogger/utilities/icons.py @@ -0,0 +1,83 @@ +#---------------------------------------------------------------------- +# This file was generated by /usr/local/bin/img2py +# +from wx.lib.embeddedimage import PyEmbeddedImage + +updateIcon = PyEmbeddedImage( + "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" + "gg==") + +#---------------------------------------------------------------------- +# This file was generated by /usr/local/bin/img2py +# +from wx.lib.embeddedimage import PyEmbeddedImage + +developerIcon= PyEmbeddedImage( + "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") + diff --git a/dumblogger/utilities/setup.py b/dumblogger/utilities/setup.py new file mode 100644 index 0000000..6f7154d --- /dev/null +++ b/dumblogger/utilities/setup.py @@ -0,0 +1,31 @@ +""" +This is a setup.py script altered from one generated by py2applet + +Usage: + python setup.py py2app +""" + +from setuptools import setup + +# A custom plist for letting it associate with all files. +Plist = dict(CFBundleDocumentTypes= [dict(CFBundleTypeExtensions=["*"], + #CFBundleTypeName="kUTTypeText", # this should be text files, but I'm not sure the details. + CFBundleTypeRole="Editor"), + ] + ) + + +APP = ['ConsoleApp.py'] +DATA_FILES = [] +OPTIONS = {'argv_emulation': True, # this puts the names of dropped files into sys.argv when starting the app. + 'iconfile': 'console.icns', + 'plist': Plist, + } + + +setup( + app=APP, + data_files=DATA_FILES, + options={'py2app': OPTIONS}, + setup_requires=['py2app'], +)
\ No newline at end of file diff --git a/dumblogger/utilities/software_update.icns b/dumblogger/utilities/software_update.icns Binary files differnew file mode 100644 index 0000000..8da364f --- /dev/null +++ b/dumblogger/utilities/software_update.icns diff --git a/dumblogger/utilities/software_update.ico b/dumblogger/utilities/software_update.ico Binary files differnew file mode 100644 index 0000000..c8c8f02 --- /dev/null +++ b/dumblogger/utilities/software_update.ico diff --git a/dumblogger/utilities/software_update_32x32x32.png b/dumblogger/utilities/software_update_32x32x32.png Binary files differnew file mode 100644 index 0000000..6a1576f --- /dev/null +++ b/dumblogger/utilities/software_update_32x32x32.png |
