2012-11-18 14:14:17 +00:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
2012-11-21 11:06:39 +00:00
import sys , os , random , copy , struct
2012-11-18 14:14:17 +00:00
2012-11-23 13:03:40 +00:00
from datetime import datetime
2012-11-21 11:06:39 +00:00
from collections import deque
2012-11-18 14:14:17 +00:00
from operator import attrgetter
import xml . etree . ElementTree as etree
import pylab
2012-11-22 06:22:33 +00:00
import numpy
2012-11-18 14:14:17 +00:00
from PyQt4 import QtGui , QtCore
from numpy import arange , sin , pi , array , linspace , arange
from matplotlib . backends . backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib . figure import Figure
from matplotlib . lines import Line2D
from matplotlib . path import Path
import matplotlib . patches as patches
2012-11-21 11:06:39 +00:00
2012-11-21 19:39:22 +00:00
from mpltools import annotation
2012-11-18 14:14:17 +00:00
progname = os . path . basename ( sys . argv [ 0 ] )
progversion = " 0.1 "
2012-11-20 15:55:22 +00:00
def calc_colors ( count ) :
2012-11-21 11:06:39 +00:00
if count == 1 :
return [ QtGui . QColor ( 0 , 255 , 0 ) , ]
2012-11-20 15:55:22 +00:00
r = 0
g = 255
step = int ( 512. / ( count - 1 ) )
colors = list ( )
for i in range ( count ) :
colors . append ( QtGui . QColor ( r , g , 0 ) )
if r < 255 :
r + = step
if r > 255 :
2012-11-21 11:06:39 +00:00
g - = ( r - 256 )
2012-11-20 15:55:22 +00:00
r = 255
2012-11-21 11:06:39 +00:00
g = max ( 0 , g )
2012-11-20 15:55:22 +00:00
else :
g - = step
g = max ( 0 , g )
return colors
2012-11-21 11:06:39 +00:00
def set_colors ( temp_levels ) :
colors = calc_colors ( len ( temp_levels ) - 1 )
ix = 0
for temp_level in temp_levels :
if not temp_level . is_env :
temp_level . color = colors [ ix ]
ix + = 1
else :
temp_level . color = QtGui . QColor ( " black " )
2012-11-23 13:03:40 +00:00
def get_valid_neigbors ( temp_level , temp_levels ) :
ix = temp_levels . index ( temp_level )
return temp_levels [ ix - 1 ] , temp_levels [ ix + 1 ]
2012-11-21 11:06:39 +00:00
def create_profile_header ( x_list , y_list ) :
tpl = " #ifndef _H_SOLDER_PROFILE \n " \
" #define _H_SOLDER_PROFILE \n " \
" \n " \
" %s \n " \
" \n " \
" }; \n " \
" \n " \
" #endif \n "
data_tpl = " unsigned int profile_ %d [ %d ][2] = \n %s \n " \
s = list ( )
ix = 0
for x , y in zip ( x_list , y_list ) :
tmp = list ( )
for a , b in zip ( x , y ) :
tmp . append ( " { %d , %d } " % ( a , b ) )
s . append ( data_tpl % ( ix , len ( x ) , " \n " . join ( tmp ) ) )
ix + = 1
open ( " test.h " , " w " ) . write ( tpl % ( " \n " . join ( s ) ) )
def create_profile_packet ( x , y ) :
# msg = [length, x_0, y_0,x_1, y_1, ..., x_length-1, y_length-1]
tmp = [ len ( x ) * 2 * 2 , ]
for a , b in zip ( x , y ) :
tmp . append ( a )
tmp . append ( b )
tpl = " H " + ( len ( x ) * 2 ) * " H "
res = struct . pack ( tpl , * tmp )
return res
2012-11-20 15:55:22 +00:00
def getTemperature ( ) :
return 20.
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
class TempLevel ( QtCore . QObject ) :
2012-11-20 15:55:22 +00:00
def __init__ ( self , name , temp , is_env = False ) :
2012-11-23 13:03:40 +00:00
super ( TempLevel , self ) . __init__ ( )
2012-11-18 14:14:17 +00:00
self . name = name
self . temp = temp
2012-11-20 15:55:22 +00:00
self . is_env = is_env
self . color = None
2012-11-18 14:14:17 +00:00
2012-11-23 13:03:40 +00:00
def __str__ ( self ) :
return " <TempLevel: name= %r , temp= %r > " % ( self . name , self . temp )
def __lt__ ( self , other ) :
return self . temp < other . temp
def __le__ ( self , other ) :
return self . temp < = other . temp
def __eq__ ( self , other ) :
return self . temp == other . temp
def is_between ( self , tl1 , tl2 ) :
tmp = [ tl1 , tl2 , self ]
tmp . sort ( )
return self == tmp [ 1 ]
__repr__ = __str__
2012-11-22 18:59:40 +00:00
class TempLevelModel ( QtCore . QAbstractTableModel ) :
solder_changed = QtCore . pyqtSignal ( )
def __init__ ( self , parent ) :
super ( TempLevelModel , self ) . __init__ ( parent )
self . _changed = False
self . temp_levels = list ( )
self . headerdata = [ u " Name " , u " Temperature (°C) " ]
def headerData ( self , col , orientation , role ) :
if orientation == QtCore . Qt . Horizontal and role == QtCore . Qt . DisplayRole :
return QtCore . QVariant ( self . headerdata [ col ] )
return QtCore . QVariant ( )
def rowCount ( self , parent ) :
return len ( self . temp_levels )
def columnCount ( self , parent ) :
return 2
def data ( self , index , role ) :
if not index . isValid ( ) :
return QtCore . QVariant ( )
if role == QtCore . Qt . DisplayRole :
col = index . column ( )
if col == 0 :
return QtCore . QVariant ( self . temp_levels [ index . row ( ) ] . name )
else :
return QtCore . QVariant ( self . temp_levels [ index . row ( ) ] . temp )
if index . column ( ) == 0 and role == QtCore . Qt . DecorationRole :
p = QtGui . QPixmap ( 10 , 10 )
color = self . temp_levels [ index . row ( ) ] . color
p . fill ( color )
return p
return QtCore . QVariant ( )
def flags ( self , index ) :
if not index . isValid ( ) :
return 0
return QtCore . Qt . ItemFlags ( QtCore . Qt . ItemIsEnabled | QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEditable )
def setData ( self , index , variant , role ) :
if index . isValid ( ) and role == QtCore . Qt . EditRole :
col = index . column ( )
if col == 0 :
self . temp_levels [ index . row ( ) ] . name = str ( variant . toString ( ) )
elif col == 1 :
self . temp_levels [ index . row ( ) ] . temp = variant . toInt ( ) [ 0 ]
print " emit solder_changed "
self . solder_changed . emit ( )
return True
return False
def remove_temp_level ( self , index ) :
tmp = self . temp_levels [ index ]
del self . temp_levels [ index ]
self . reset ( )
self . solder_changed . emit ( )
return tmp
def add_temp_level ( self , index , temp_level ) :
self . temp_levels . insert ( index . row ( ) + 1 , temp_level )
set_colors ( self . temp_levels )
self . reset ( )
self . solder_changed . emit ( )
def setTempLevels ( self , temp_levels ) :
assert isinstance ( temp_levels , list )
self . temp_levels = temp_levels
self . reset ( )
def clear ( self ) :
self . temp_levels = list ( )
self . reset ( )
2012-11-23 13:03:40 +00:00
2012-11-22 18:59:40 +00:00
class TempLevelWidget ( QtGui . QWidget ) :
temp_level_removed = QtCore . pyqtSignal ( TempLevel )
2012-11-23 13:03:40 +00:00
temp_levels_changed = QtCore . pyqtSignal ( )
2012-11-22 18:59:40 +00:00
solder_changed = QtCore . pyqtSignal ( )
def __init__ ( self , parent , readonly = False ) :
super ( TempLevelWidget , self ) . __init__ ( parent )
self . readonly = readonly
self . temp_level_model = TempLevelModel ( self )
self . temp_level_view = QtGui . QTableView ( )
self . temp_level_view . setModel ( self . temp_level_model )
self . temp_level_view . verticalHeader ( ) . setVisible ( False )
self . temp_level_view . resizeColumnsToContents ( )
self . temp_level_view . horizontalHeader ( ) . setStretchLastSection ( True )
self . temp_level_view . setSelectionBehavior ( QtGui . QAbstractItemView . SelectRows )
h = QtGui . QHBoxLayout ( )
h . addWidget ( self . temp_level_view )
self . setLayout ( h )
self . connect (
self . temp_level_view ,
QtCore . SIGNAL ( " clicked(QModelIndex) " ) ,
self . temp_level_selected )
if not readonly :
self . controls = AddRemoveWidget ( self )
h . addWidget ( self . controls )
self . connect (
self . controls . add_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . add_temp_level )
self . connect (
self . controls . remove_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . remove_temp_level )
self . connect (
self . controls . up_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . temp_level_up )
self . connect (
self . controls . down_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . temp_level_down )
self . connect (
self . temp_level_model ,
QtCore . SIGNAL ( " solder_changed() " ) ,
self . _solder_changed )
def _solder_changed ( self ) :
print self . _solder_changed
self . solder_changed . emit ( )
def setData ( self , solder ) :
self . temp_level_model . setTempLevels ( solder . temp_levels )
self . temp_level_view . resizeColumnsToContents ( )
2012-11-23 13:03:40 +00:00
self . temp_level_view . setCurrentIndex ( self . temp_level_model . index ( 0 , 0 ) )
2012-11-22 18:59:40 +00:00
def add_temp_level ( self ) :
index = self . temp_level_view . currentIndex ( )
self . temp_level_model . add_temp_level ( index , TempLevel ( " new " + str ( self . temp_level_model . rowCount ( None ) ) , 0 ) )
self . temp_level_view . setCurrentIndex ( self . temp_level_model . index ( index . row ( ) + 1 , 0 ) )
2012-11-23 13:03:40 +00:00
self . temp_levels_changed . emit ( )
2012-11-22 18:59:40 +00:00
def remove_temp_level ( self ) :
self . temp_level_removed . emit (
self . temp_level_model . remove_temp_level (
self . temp_level_view . currentIndex ( ) . row ( ) ) )
self . solder_changed . emit ( )
def temp_level_up ( self ) :
dst_row = self . temp_level_view . currentIndex ( ) . row ( )
self . temp_level_model . temp_levels [ dst_row - 1 ] , self . temp_level_model . temp_levels [ dst_row ] = self . temp_level_model . temp_levels [ dst_row ] , self . temp_level_model . temp_levels [ dst_row - 1 ]
self . temp_level_model . reset ( )
self . solder_changed . emit ( )
def temp_level_down ( self ) :
dst_row = self . selected_temp_levels_view . currentIndex ( ) . row ( )
self . temp_level_model . temp_levels [ dst_row ] , self . temp_level_model . temp_levels [ dst_row + 1 ] = self . temp_level_model . temp_levels [ dst_row + 1 ] , self . temp_level_model . temp_levels [ dst_row ]
self . temp_level_model . reset ( )
self . solder_changed . emit ( )
def temp_level_selected ( self , index ) :
if index . isValid ( ) :
row = index . row ( )
if not self . readonly :
is_env = self . temp_level_model . temp_levels [ row ] . is_env
#is_end = row == len(self.temp_level_model.temp_levels) - 1
#self.controls.add_button.setEnabled(not is_end)
self . controls . remove_button . setEnabled ( not is_env )
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
class Solder ( QtCore . QObject ) :
2012-11-20 15:55:22 +00:00
2012-11-22 06:22:33 +00:00
log_message = QtCore . pyqtSignal ( str )
2012-11-22 16:49:57 +00:00
def __init__ ( self , filename , name = str ( ) , description = str ( ) , parent = None ) :
2012-11-22 06:22:33 +00:00
super ( Solder , self ) . __init__ ( parent )
2012-11-22 16:49:57 +00:00
self . filename = filename
2012-11-20 15:55:22 +00:00
self . name = name
self . description = description
self . temp_levels = list ( )
2012-11-18 14:14:17 +00:00
self . durations = list ( )
self . rates = list ( )
2012-11-21 11:06:39 +00:00
self . changed = False
2012-11-18 14:14:17 +00:00
def __unicode__ ( self ) :
return unicode ( self . name )
def __str__ ( self ) :
return self . name
2012-11-20 15:55:22 +00:00
def add_temp_level ( self , name , temp , is_env ) :
s = TempLevel ( name , temp , is_env )
self . temp_levels . append ( s )
2012-11-18 14:14:17 +00:00
return s
def add_rate ( self , states , rate ) :
2012-11-20 15:55:22 +00:00
self . rates . append ( [ states , rate ] )
2012-11-18 14:14:17 +00:00
def add_duration ( self , states , duration ) :
2012-11-20 15:55:22 +00:00
self . durations . append ( [ states , duration ] )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
def get_temp_level_by_name ( self , name ) :
assert isinstance ( name , basestring )
for i in self . temp_levels :
2012-11-18 14:14:17 +00:00
if i . name == name :
return i
return None
2012-11-20 15:55:22 +00:00
def get_temp_level ( self , ix ) :
assert isinstance ( ix , int )
return self . temp_levels [ ix ]
2012-11-22 06:22:33 +00:00
def calc_rate ( self , x1 , y1 , x2 , y2 ) :
return ( y2 - y1 ) / ( x2 - x1 )
2012-11-23 13:03:40 +00:00
def check_duration_constraints ( self , temp_level , used , ix ) :
2012-11-22 06:22:33 +00:00
x = list ( )
y = list ( )
temp_levels = None
value = None
2012-11-23 13:03:40 +00:00
dx = 0
2012-11-22 06:22:33 +00:00
for temp_levels , value in self . durations :
tl_len = len ( temp_levels )
2012-11-23 13:03:40 +00:00
print " check dur " , dx , temp_level , repr ( temp_levels ) , self . ud
if temp_levels and temp_levels [ 0 ] == temp_level and tl_len > 1 and dx not in self . ud :
2012-11-22 06:22:33 +00:00
if temp_level not in used :
used . add ( temp_level )
x . append ( self . time )
y . append ( temp_level . temp )
2012-11-23 13:03:40 +00:00
self . ud . add ( dx )
print " using duration constraint " , dx
2012-11-22 06:22:33 +00:00
if tl_len == 2 :
2012-11-23 13:03:40 +00:00
ix = self . temp_levels . index ( temp_levels [ 1 ] )
2012-11-22 06:22:33 +00:00
y . append ( temp_levels [ 1 ] . temp )
used . add ( temp_levels [ 1 ] )
self . time + = value
x . append ( self . time )
elif tl_len > = 3 :
2012-11-23 13:03:40 +00:00
ix = self . temp_levels . index ( temp_levels [ - 1 ] )
2012-11-22 06:22:33 +00:00
part = value / ( tl_len - 1 )
for tl in temp_levels [ 1 : ] :
used . add ( tl )
self . time + = part
x . append ( self . time )
y . append ( tl . temp )
self . log . append ( " * Duration connection: TempLevel %r connected to TempLevels %r " % ( temp_level . name , [ tl . name for tl in temp_levels [ 1 : ] ] ) )
2012-11-23 13:03:40 +00:00
return x , y , ix
dx + = 1
raise Exception ( )
2012-11-22 06:22:33 +00:00
2012-11-23 13:03:40 +00:00
def check_rate_constraints ( self , temp_level , used , ix ) :
2012-11-22 06:22:33 +00:00
x = list ( )
y = list ( )
2012-11-23 13:03:40 +00:00
rx = 0
2012-11-22 06:22:33 +00:00
for temp_levels , value in self . rates :
tl_len = len ( temp_levels )
2012-11-23 13:03:40 +00:00
print " check rate " , rx , temp_level , repr ( temp_levels ) , self . ur
if temp_levels and tl_len > 1 and rx not in self . ur and ( temp_levels [ 0 ] == temp_level or temp_level . is_between ( * temp_levels ) ) :
if temp_level < temp_levels [ 1 ] and value < 0 :
self . log . append ( " !RateError: negative rate for increasing temp levels is wrong " )
elif temp_level > temp_levels [ 1 ] and value > 0 :
self . log . append ( " !RateError: positive rate for decreasing temp levels is wrong " )
2012-11-22 06:22:33 +00:00
if temp_level not in used :
used . add ( temp_level )
x . append ( self . time )
y . append ( temp_level . temp )
2012-11-23 13:03:40 +00:00
self . ur . add ( rx )
print " using rate constraint " , rx
2012-11-22 06:22:33 +00:00
self . time + = ( temp_levels [ 1 ] . temp - temp_level . temp ) / value
used . add ( temp_levels [ 1 ] )
x . append ( self . time )
y . append ( temp_levels [ 1 ] . temp )
2012-11-23 13:03:40 +00:00
ix = self . temp_levels . index ( temp_levels [ - 1 ] )
2012-11-22 06:22:33 +00:00
self . log . append ( " * Rate connection: TempLevel %r connected to TempLevels %r " % ( temp_level . name , [ tl . name for tl in temp_levels [ 1 : ] ] ) )
2012-11-23 13:03:40 +00:00
return x , y , ix
rx + = 1
raise Exception ( )
2012-11-22 06:22:33 +00:00
2012-11-18 14:14:17 +00:00
def calc_profile ( self ) :
2012-11-23 13:03:40 +00:00
print self . calc_profile
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
self . log = list ( )
x = list ( )
y = list ( )
duration_points = dict ( )
rate_points = dict ( )
self . time = 0
used = set ( )
unused = list ( )
2012-11-23 13:03:40 +00:00
ix = 0
last = len ( self . temp_levels )
self . ud = set ( )
self . ur = set ( )
count = len ( self . durations ) + len ( self . rates )
print " max rounds " , count
while 1 :
print " while " , ix , last , x , y , self . ud , self . ur
temp_level = self . temp_levels [ ix ]
count - = 1
2012-11-22 06:22:33 +00:00
2012-11-23 13:03:40 +00:00
try :
dur_x , dur_y , dur_new_ix = self . check_duration_constraints ( temp_level , used , ix )
ix = dur_new_ix
print " dur_new_ix " , dur_new_ix
2012-11-22 06:22:33 +00:00
x . extend ( dur_x )
y . extend ( dur_y )
2012-11-23 13:03:40 +00:00
except Exception , e :
print e
try :
rate_x , rate_y , rate_new_ix = self . check_rate_constraints ( temp_level , used , ix )
ix = rate_new_ix
print " rate_new_ix " , rate_new_ix
x . extend ( rate_x )
y . extend ( rate_y )
except Exception , e :
print e
ix + = 1
#if temp_level not in used:
#unused.append(temp_level)
if ( y and y [ - 1 ] == y [ 0 ] ) or count < = 0 :
break
2012-11-22 06:22:33 +00:00
self . log . append ( " " )
map ( self . log . append , [ " * Missing Connection: %r " % tl . name for tl in unused ] )
self . log_message . emit ( " \n " . join ( self . log ) )
del self . log
2012-11-22 16:49:57 +00:00
return array ( map ( float , x ) ) , array ( map ( float , y ) ) , min ( x ) , max ( x ) , min ( y ) , max ( y ) , used , unused
2012-11-18 14:14:17 +00:00
@staticmethod
2012-11-22 06:22:33 +00:00
def unpack ( filename , parent ) :
2012-11-18 14:14:17 +00:00
xmltree = etree . parse ( filename )
root = xmltree . getroot ( )
2012-11-20 15:55:22 +00:00
solder_node = root [ 0 ]
2012-11-22 16:49:57 +00:00
s = Solder ( filename , solder_node . attrib [ " name " ] , solder_node . attrib [ " description " ] , parent )
2012-11-20 15:55:22 +00:00
env_count = 0
for temp_level in solder_node . findall ( " state " ) :
tstr = temp_level . attrib [ " temperature " ]
is_env = False
try :
temp = int ( tstr )
except ValueError :
if tstr == " $ENV " :
temp = getTemperature ( )
is_env = True
env_count + = 1
s . add_temp_level ( temp_level . attrib [ " name " ] , temp , is_env )
2012-11-21 11:06:39 +00:00
set_colors ( s . temp_levels )
2012-11-20 15:55:22 +00:00
for duration in solder_node . findall ( " duration " ) :
temp_levels = list ( )
for temp_level in duration :
temp_levels . append ( s . get_temp_level_by_name ( temp_level . attrib [ " name " ] ) )
s . add_duration ( temp_levels , int ( duration . attrib [ " value " ] ) )
for rate in solder_node . findall ( " rate " ) :
temp_levels = list ( )
for temp_level in rate :
temp_levels . append ( s . get_temp_level_by_name ( temp_level . attrib [ " name " ] ) )
s . add_rate ( temp_levels , int ( rate . attrib [ " value " ] ) )
2012-11-18 14:14:17 +00:00
return s
2012-11-22 16:49:57 +00:00
def save ( self ) :
2012-11-21 19:39:22 +00:00
if self . changed :
solder_node = etree . Element ( " solder_type " , { " name " : self . name , " description " : self . description } )
for temp_level in self . temp_levels :
temp = temp_level . is_env and " $ENV " or str ( temp_level . temp )
solder_node . append ( etree . Element ( " state " , { " name " : temp_level . name , " temperature " : temp } ) )
for temp_levels , value in self . durations :
duration = etree . Element ( " duration " , { " value " : str ( value ) } )
for temp_level in temp_levels :
duration . append ( etree . Element ( " state " , { " name " : temp_level . name } ) )
solder_node . append ( duration )
for temp_levels , value in self . rates :
rate = etree . Element ( " rate " , { " value " : str ( value ) } )
for temp_level in temp_levels :
rate . append ( etree . Element ( " state " , { " name " : temp_level . name } ) )
solder_node . append ( rate )
2012-11-22 18:59:40 +00:00
dirname = SolderListModel . dirname ( )
2012-11-21 19:39:22 +00:00
root = etree . Element ( " xml " )
root . append ( solder_node )
2012-11-22 18:59:40 +00:00
if self . filename is None :
self . filename = os . path . join ( dirname , self . name + " .xml " )
2012-11-22 16:49:57 +00:00
etree . ElementTree ( root ) . write ( self . filename , " UTF-8 " , True )
2012-11-21 19:39:22 +00:00
self . changed = False
2012-11-22 16:49:57 +00:00
def setChanged ( self ) :
print self . setChanged
self . changed = True
2012-11-18 14:14:17 +00:00
2012-11-20 20:33:15 +00:00
2012-11-18 14:14:17 +00:00
class SolderListModel ( QtCore . QAbstractListModel ) :
def __init__ ( self , parent = None , * args ) :
""" datain: a list where each item is a row
"""
super ( SolderListModel , self ) . __init__ ( parent , * args )
2012-11-21 19:39:22 +00:00
self . reload ( )
2012-11-20 15:55:22 +00:00
2012-11-18 14:14:17 +00:00
def rowCount ( self , parent = QtCore . QModelIndex ( ) ) :
return len ( self . listdata )
2012-11-21 19:39:22 +00:00
def reload ( self ) :
2012-11-22 18:59:40 +00:00
dirname = self . dirname ( )
2012-11-21 19:39:22 +00:00
dirlisting = filter ( lambda x : os . path . splitext ( x ) [ 1 ] == " .xml " , os . listdir ( dirname ) )
self . listdata = [ ]
for p in dirlisting :
2012-11-22 06:22:33 +00:00
self . listdata . append ( Solder . unpack ( os . path . join ( dirname , p ) , self ) )
2012-11-21 19:39:22 +00:00
self . listdata . sort ( key = lambda x : x . name )
self . reset ( )
2012-11-18 14:14:17 +00:00
def headerData ( self , col , orientation , role ) :
if orientation == QtCore . Qt . Horizontal and role == QtCore . Qt . DisplayRole :
return QtCore . QVariant ( " Solder Paste " )
return QtCore . QVariant ( )
def data ( self , index , role ) :
2012-11-22 16:49:57 +00:00
if not index . isValid ( ) :
2012-11-18 14:14:17 +00:00
return QtCore . QVariant ( )
2012-11-22 16:49:57 +00:00
solder = self . listdata [ index . row ( ) ]
if role == QtCore . Qt . DisplayRole :
return QtCore . QVariant ( solder . name )
elif role == QtCore . Qt . DecorationRole and solder . changed :
return QtGui . QIcon . fromTheme ( " document-save " )
2012-11-21 19:39:22 +00:00
def setData ( self , index , variant , role ) :
if index . isValid ( ) and role == QtCore . Qt . EditRole :
new_name = str ( variant . toString ( ) )
if new_name and new_name != " " :
self . listdata [ index . row ( ) ] . name = new_name
self . listdata [ index . row ( ) ] . changed = True
return True
return False
def flags ( self , index ) :
if not index . isValid ( ) :
return 0
return QtCore . Qt . ItemFlags ( QtCore . Qt . ItemIsEnabled | QtCore . Qt . ItemIsSelectable | QtCore . Qt . ItemIsEditable )
2012-11-20 20:33:15 +00:00
def create_solder ( self ) :
2012-11-23 13:03:40 +00:00
solder = Solder ( None , datetime . now ( ) . strftime ( " % Y- % M- % D % H: % m: %s " ) , " " )
2012-11-21 11:06:39 +00:00
tl = solder . add_temp_level ( " environment temp " , getTemperature ( ) , True )
tl . color = QtGui . QColor ( 0 , 0 , 0 )
2012-11-20 20:33:15 +00:00
self . listdata . append ( solder )
self . reset ( )
2012-11-22 18:59:40 +00:00
@staticmethod
def dirname ( ) :
return os . path . join ( os . path . dirname ( __file__ ) , " solder_types " )
2012-11-23 13:03:40 +00:00
def check_name ( self , name ) :
for solder in self . listdata :
if name == solder . name :
return False
return True
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
class SolderWidget ( QtGui . QWidget ) :
def __init__ ( self , parent , readonly = False ) :
super ( SolderWidget , self ) . __init__ ( parent )
self . solder_model = SolderListModel ( self )
self . solder_view = QtGui . QListView ( )
self . solder_view . setModel ( self . solder_model )
self . solder_controls = AddRemoveWidget ( self , False )
2012-11-20 15:55:22 +00:00
2012-11-22 18:59:40 +00:00
layout = QtGui . QHBoxLayout ( self )
layout . addWidget ( self . solder_view , 3 )
layout . addWidget ( self . solder_controls , 1 )
2012-11-20 15:55:22 +00:00
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
self . connect (
self . solder_controls . add_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . solder_model . create_solder )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
self . connect (
self . solder_controls . remove_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . remove_solder )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
self . solder_view . setCurrentIndex ( self . solder_model . index ( 0 , 0 ) )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
def remove_solder ( self ) :
index = self . solder_view . currentIndex ( )
solder = self . solder_model . listdata [ index . row ( ) ]
try :
os . remove ( solder . filename )
except OSError , e :
print e
pass
del self . solder_model . listdata [ index . row ( ) ]
self . solder_model . reset ( )
new_index = self . solder_model . index ( 0 )
self . solder_view . setCurrentIndex ( new_index )
return new_index
def save_solder ( self , index ) :
self . solder_model . listdata [ index . row ( ) ] . save ( )
self . solder_model . reset ( )
new_index = self . solder_model . index ( self . solder_model . listdata . index ( self . plotter . solder ) )
self . solder_widget . solder_view . setCurrentIndex ( new_index )
2012-11-20 15:55:22 +00:00
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
class Plotter ( FigureCanvas ) :
2012-11-18 14:14:17 +00:00
""" A canvas that updates itself every second with a new plot. """
2012-11-21 19:39:22 +00:00
2012-11-18 14:14:17 +00:00
def __init__ ( self , parent , myapp , width , height , dpi ) :
self . fig = Figure ( figsize = ( width , height ) , dpi = dpi )
2012-11-20 15:55:22 +00:00
super ( Plotter , self ) . __init__ ( self . fig )
2012-11-18 14:14:17 +00:00
self . axes = self . fig . add_subplot ( 111 )
2012-11-22 06:22:33 +00:00
#self.fig.subplots_adjust(
#left=0.1,
#bottom=0.05,
#right=0.9,
#top=0.95,
#wspace=0,
#hspace=0
#)
2012-11-18 14:14:17 +00:00
2012-11-21 19:39:22 +00:00
self . axes . set_axis_bgcolor ( ' white ' )
2012-11-18 14:14:17 +00:00
self . axes . set_title ( u ' reflow profile ' , size = 12 )
self . axes . set_xlabel ( u ' time (seconds) ' , size = 12 )
self . axes . set_ylabel ( u ' temperature (°C) ' , size = 12 )
2012-11-20 15:55:22 +00:00
self . axes . set_ymargin ( 0 )
self . axes . set_xmargin ( 0 )
2012-11-18 14:14:17 +00:00
self . setParent ( parent )
self . myapp = myapp
self . solder = None
self . plot_data , = self . axes . plot ( [ ] , linewidth = 1.0 , color = ( 0 , 0 , 1 ) , zorder = 10 )
2012-11-20 15:55:22 +00:00
#self.selection_data, = self.axes.plot([], linewidth=1.0, color=(1,1,1), zorder=5)
2012-11-18 14:14:17 +00:00
FigureCanvas . setSizePolicy ( self ,
QtGui . QSizePolicy . Expanding ,
QtGui . QSizePolicy . Expanding )
FigureCanvas . updateGeometry ( self )
timer = QtCore . QTimer ( self )
QtCore . QObject . connect ( timer , QtCore . SIGNAL ( " timeout() " ) , self . update_figure )
timer . start ( 1000 )
2012-11-22 16:49:57 +00:00
self . updated = False
2012-11-18 14:14:17 +00:00
def update_figure ( self ) :
2012-11-20 15:55:22 +00:00
if self . updated :
2012-11-22 18:59:40 +00:00
self . fig . lines = lines = list ( )
2012-11-22 06:22:33 +00:00
self . updated = False
2012-11-21 19:39:22 +00:00
self . axes . patches = list ( )
self . axes . texts = list ( )
self . x = list ( )
self . y = list ( )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
try :
self . x , self . y , self . xmin , self . xmax , self . ymin , self . ymax , self . used , self . unused = self . solder . calc_profile ( )
except ValueError :
self . x , self . y , self . xmin , self . xmax , self . ymin , self . ymax , self . used , self . unused = [ ] , [ ] , 0. , 300. , 0. , 300. , [ ] , self . solder . temp_levels
2012-11-21 19:39:22 +00:00
self . plot_data . set_xdata ( self . x )
self . plot_data . set_ydata ( self . y )
2012-11-18 14:14:17 +00:00
2012-11-22 16:49:57 +00:00
self . axes . set_xbound ( lower = self . xmin , upper = self . xmax + 20 )
self . axes . set_ybound ( lower = self . ymin , upper = self . ymax + 20 )
2012-11-22 18:59:40 +00:00
self . axes . set_xlim ( self . xmin , self . xmax + 20 , auto = True )
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
self . axes . set_yticks ( self . y )
2012-11-21 11:06:39 +00:00
self . axes . set_xticks ( self . x )
2012-11-18 14:14:17 +00:00
2012-11-22 16:49:57 +00:00
for ix , ( a , b ) in enumerate ( zip ( self . x [ : - 1 ] , self . y [ : - 1 ] ) ) :
slope = ( self . y [ ix + 1 ] - b ) / ( self . x [ ix + 1 ] - a )
if not ( numpy . isnan ( slope ) or numpy . isinf ( slope ) ) :
origin = ( a + 10 , b )
annotation . slope_marker ( origin , slope , ax = self . axes )
2012-11-18 14:14:17 +00:00
2012-11-22 16:49:57 +00:00
self . axes . legend ( ( " Estimated profile " , ) , loc = 2 )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
for temp_level in self . solder . temp_levels :
if not temp_level . is_env :
line = Line2D ( [ 0 , self . xmax + 20 ] , [ temp_level . temp , temp_level . temp ] ,
transform = self . axes . transData , figure = self . fig , color = str ( temp_level . color . name ( ) ) , label = " name " , zorder = 1 )
lines . append ( line )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
self . draw ( )
2012-11-18 14:14:17 +00:00
2012-11-21 19:39:22 +00:00
def solder_changed ( self ) :
2012-11-22 16:49:57 +00:00
self . solder . setChanged ( )
2012-11-22 06:22:33 +00:00
self . updated = True
2012-11-21 19:39:22 +00:00
2012-11-21 11:06:39 +00:00
def setData ( self , solder ) :
self . solder = solder
self . updated = True
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
class AddRemoveWidget ( QtGui . QWidget ) :
def __init__ ( self , parent , with_upown = True ) :
#super(AddRemoveWidget, self).__init__(parent)
QtGui . QWidget . __init__ ( self , parent )
2012-11-21 19:39:22 +00:00
self . add_button = QtGui . QPushButton ( QtGui . QIcon . fromTheme ( " list-add " ) , " " )
self . remove_button = QtGui . QPushButton ( QtGui . QIcon . fromTheme ( " list-remove " ) , " " )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
sh = " QPushButton:disabled { background-color: #555555; } "
self . remove_button . setStyleSheet ( sh )
self . add_button . setStyleSheet ( sh )
self . _layout = QtGui . QVBoxLayout ( self )
self . _layout . addWidget ( self . add_button )
self . _layout . addWidget ( self . remove_button )
if with_upown :
2012-11-21 19:39:22 +00:00
self . up_button = QtGui . QPushButton ( QtGui . QIcon . fromTheme ( " go-up " ) , " " )
self . down_button = QtGui . QPushButton ( QtGui . QIcon . fromTheme ( " go-down " ) , " " )
2012-11-20 15:55:22 +00:00
self . _layout . addWidget ( self . up_button )
self . _layout . addWidget ( self . down_button )
2012-11-21 11:06:39 +00:00
self . up_button . setStyleSheet ( sh )
self . down_button . setStyleSheet ( sh )
2012-11-20 15:55:22 +00:00
self . _layout . addStretch ( 4 )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
class AddRemoveValueWidget ( AddRemoveWidget ) :
def __init__ ( self , parent ) :
super ( AddRemoveValueWidget , self ) . __init__ ( parent )
2012-11-18 14:14:17 +00:00
self . value = QtGui . QSpinBox ( self )
2012-11-20 15:55:22 +00:00
self . value . setRange ( - 500 , 500 )
self . _layout . addWidget ( self . value )
class ConstraintListModel ( QtCore . QAbstractListModel ) :
def __init__ ( self , parent = None , * args ) :
""" datain: a list where each item is a row
"""
super ( ConstraintListModel , self ) . __init__ ( parent , * args )
self . constraint_list = list ( )
def rowCount ( self , parent = QtCore . QModelIndex ( ) ) :
return len ( self . constraint_list )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
def headerData ( self , col , orientation , role ) :
if orientation == QtCore . Qt . Horizontal and role == QtCore . Qt . DisplayRole :
return QtCore . QVariant ( " Solder Paste " )
return QtCore . QVariant ( )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
def data ( self , index , role ) :
if index . isValid ( ) and role == QtCore . Qt . DisplayRole :
return QtCore . QVariant ( index . row ( ) + 1 )
else :
return QtCore . QVariant ( )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
def append_constraint ( self ) :
self . constraint_list . append ( [ [ ] , 0 ] )
self . reset ( )
def remove_constraint ( self ) :
del self . constraint_list [ self . currentIndex ( ) . row ( ) ]
self . reset ( )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
class ConstraintWidget ( QtGui . QWidget ) :
2012-11-21 19:39:22 +00:00
solder_changed = QtCore . pyqtSignal ( )
2012-11-21 11:06:39 +00:00
def __init__ ( self , name ) :
2012-11-20 15:55:22 +00:00
super ( ConstraintWidget , self ) . __init__ ( )
self . name = name
2012-11-21 11:06:39 +00:00
2012-11-20 15:55:22 +00:00
self . spinbox_block = False
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
self . constraint_model = ConstraintListModel ( self ) # constraint selection
2012-11-23 13:03:40 +00:00
self . temp_levels_model = TempLevelModel ( self ) # temp_level selection pool
self . selected_temp_levels_model = TempLevelModel ( self ) # selected temp_levels
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
self . controls = AddRemoveValueWidget ( self )
self . constraint_controls = AddRemoveWidget ( self , False )
2012-11-18 14:14:17 +00:00
2012-11-21 19:39:22 +00:00
self . controls . add_button . setText ( u " " )
self . controls . remove_button . setText ( u " " )
2012-11-18 14:14:17 +00:00
2012-11-21 19:39:22 +00:00
self . constraint_controls . add_button . setText ( u " " )
self . constraint_controls . remove_button . setText ( u " " )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
self . constraint_view = QtGui . QListView ( self )
self . constraint_view . setModel ( self . constraint_model )
2012-11-23 13:03:40 +00:00
self . temp_levels_view = QtGui . QListView ( self )
self . temp_levels_view . setModel ( self . temp_levels_model )
2012-11-20 15:55:22 +00:00
self . selected_temp_levels_view = QtGui . QListView ( self )
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_view . setModel ( self . selected_temp_levels_model )
2012-11-18 14:14:17 +00:00
h = QtGui . QHBoxLayout ( )
2012-11-20 15:55:22 +00:00
h . addWidget ( self . constraint_view , 1 )
h . addWidget ( self . constraint_controls , 1 )
2012-11-23 13:03:40 +00:00
h . addWidget ( self . temp_levels_view , 3 )
2012-11-20 15:55:22 +00:00
h . addWidget ( self . controls , 1 )
h . addWidget ( self . selected_temp_levels_view , 3 )
2012-11-21 19:39:22 +00:00
self . controls . add_button . setIcon ( QtGui . QIcon . fromTheme ( " go-next " ) )
self . controls . remove_button . setIcon ( QtGui . QIcon . fromTheme ( " go-previous " ) )
2012-11-18 14:14:17 +00:00
self . setLayout ( h )
self . connect (
2012-11-20 15:55:22 +00:00
self . constraint_view ,
2012-11-18 14:14:17 +00:00
QtCore . SIGNAL ( " clicked(QModelIndex) " ) ,
2012-11-20 15:55:22 +00:00
self . _constraint_selected )
self . connect (
self . controls . add_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . add_temp_level_to_constraint )
self . connect (
self . controls . remove_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . remove_temp_level_from_constraint )
2012-11-18 14:14:17 +00:00
2012-11-18 14:38:57 +00:00
self . connect (
2012-11-20 15:55:22 +00:00
self . controls . up_button ,
2012-11-18 14:38:57 +00:00
QtCore . SIGNAL ( " clicked() " ) ,
2012-11-20 15:55:22 +00:00
self . temp_level_up )
2012-11-18 14:14:17 +00:00
2012-11-18 14:38:57 +00:00
self . connect (
2012-11-20 15:55:22 +00:00
self . controls . down_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . temp_level_down )
self . connect (
self . constraint_controls . add_button ,
QtCore . SIGNAL ( " clicked() " ) ,
2012-11-21 11:06:39 +00:00
self . add_constraint )
2012-11-20 15:55:22 +00:00
self . connect (
self . constraint_controls . remove_button ,
2012-11-18 14:38:57 +00:00
QtCore . SIGNAL ( " clicked() " ) ,
self . remove_constraint )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
self . connect (
self . controls . value ,
QtCore . SIGNAL ( " valueChanged(int) " ) ,
self . constraint_value_changed )
2012-11-18 14:14:17 +00:00
2012-11-21 19:39:22 +00:00
self . connect (
self . selected_temp_levels_view ,
QtCore . SIGNAL ( " clicked(QModelIndex) " ) ,
self . selected_temp_levels_clicked )
2012-11-18 14:14:17 +00:00
def setData ( self , solder ) :
self . solder = solder
2012-11-23 13:03:40 +00:00
self . temp_levels_model . setTempLevels ( solder . temp_levels )
2012-11-21 11:06:39 +00:00
self . _set_data ( solder )
self . set_controls ( )
2012-11-23 13:03:40 +00:00
self . temp_levels_view . setCurrentIndex ( self . temp_levels_model . index ( 0 , 0 ) )
2012-11-21 11:06:39 +00:00
2012-11-21 19:39:22 +00:00
self . controls . up_button . setEnabled ( False )
self . controls . down_button . setEnabled ( False )
2012-11-21 11:06:39 +00:00
def set_controls ( self ) :
if not self . constraint_model . constraint_list :
self . controls . value . setEnabled ( False )
self . constraint_controls . remove_button . setEnabled ( False )
self . controls . add_button . setEnabled ( False )
self . controls . remove_button . setEnabled ( False )
self . controls . up_button . setEnabled ( False )
self . controls . down_button . setEnabled ( False )
else :
self . controls . value . setEnabled ( True )
self . constraint_controls . remove_button . setEnabled ( True )
self . controls . add_button . setEnabled ( True )
self . controls . remove_button . setEnabled ( True )
self . controls . up_button . setEnabled ( True )
self . controls . down_button . setEnabled ( True )
2012-11-21 19:39:22 +00:00
def selected_temp_levels_clicked ( self , index ) :
if index . isValid ( ) :
self . controls . up_button . setEnabled ( True )
self . controls . down_button . setEnabled ( True )
2012-11-21 11:06:39 +00:00
def add_constraint ( self ) :
self . constraint_model . append_constraint ( )
2012-11-22 18:59:40 +00:00
new_index = self . constraint_model . rowCount ( ) - 1
self . constraint_view . setCurrentIndex ( self . constraint_model . index ( new_index , 0 ) )
2012-11-21 11:06:39 +00:00
self . set_controls ( )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
def _constraint_selected ( self , index ) :
2012-11-18 14:38:57 +00:00
raise NotImplementedError ( )
2012-11-18 14:14:17 +00:00
2012-11-21 11:06:39 +00:00
def _set_data ( self , solder ) :
2012-11-18 14:14:17 +00:00
raise NotImplementedError ( )
2012-11-20 15:55:22 +00:00
def add_temp_level_to_constraint ( self ) :
2012-11-23 13:03:40 +00:00
src_row = self . temp_levels_view . currentIndex ( ) . row ( )
temp_level = self . temp_levels_model . temp_levels [ src_row ]
self . selected_temp_levels_model . temp_levels . append ( temp_level )
self . selected_temp_levels_model . reset ( )
self . selected_temp_levels_view . setCurrentIndex ( self . selected_temp_levels_model . index ( len ( self . selected_temp_levels_model . temp_levels ) - 1 , 0 ) )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-20 15:55:22 +00:00
def remove_temp_level_from_constraint ( self ) :
2012-11-23 13:03:40 +00:00
del self . selected_temp_levels_model . temp_levels [ self . selected_temp_levels_view . currentIndex ( ) . row ( ) ]
self . selected_temp_levels_model . reset ( )
2012-11-20 15:55:22 +00:00
self . selected_temp_levels_view . clearSelection ( )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-18 14:14:17 +00:00
2012-11-18 14:38:57 +00:00
def remove_constraint ( self ) :
2012-11-23 13:03:40 +00:00
src_row = self . temp_levels_view . currentIndex ( ) . row ( )
2012-11-20 15:55:22 +00:00
del self . constraint_model . constraint_list [ src_row ]
self . constraint_model . reset ( )
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . clear ( )
2012-11-21 11:06:39 +00:00
self . set_controls ( )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-20 15:55:22 +00:00
def constraint_value_changed ( self , value ) :
if self . spinbox_block :
self . spinbox_block = False
return
src_index = self . constraint_view . currentIndex ( ) . row ( )
self . constraint_model . constraint_list [ src_index ] [ 1 ] = value
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-20 15:55:22 +00:00
2012-11-23 13:03:40 +00:00
def temp_levels_changed ( self ) :
print self . temp_levels_changed
self . temp_levels_model . reset ( )
2012-11-20 15:55:22 +00:00
def slot_temp_level_removed ( self , temp_level ) :
2012-11-21 11:06:39 +00:00
deletes = deque ( )
ix = 0
for temp_levels , v in self . constraint_model . constraint_list :
if temp_level in temp_levels :
deletes . appendleft ( ix )
ix + = 1
for i in deletes :
del self . constraint_model . constraint_list [ i ]
2012-11-20 15:55:22 +00:00
self . reset ( )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-20 15:55:22 +00:00
def temp_level_up ( self ) :
dst_row = self . selected_temp_levels_view . currentIndex ( ) . row ( )
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . temp_levels [ dst_row - 1 ] , self . selected_temp_levels_model . temp_levels [ dst_row ] = self . selected_temp_levels_model . temp_levels [ dst_row ] , self . selected_temp_levels_model . temp_levels [ dst_row - 1 ]
self . selected_temp_levels_model . reset ( )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
def temp_level_down ( self ) :
dst_row = self . selected_temp_levels_view . currentIndex ( ) . row ( )
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . temp_levels [ dst_row ] , self . selected_temp_levels_model . temp_levels [ dst_row + 1 ] = self . selected_temp_levels_model . temp_levels [ dst_row + 1 ] , self . selected_temp_levels_model . temp_levels [ dst_row ]
self . selected_temp_levels_model . reset ( )
2012-11-21 19:39:22 +00:00
self . solder_changed . emit ( )
2012-11-18 14:38:57 +00:00
2012-11-18 14:14:17 +00:00
class DurationConstraintWidget ( ConstraintWidget ) :
2012-11-21 11:06:39 +00:00
def _set_data ( self , solder ) :
2012-11-20 15:55:22 +00:00
self . spinbox_block = True
2012-11-21 11:06:39 +00:00
self . constraint_model . constraint_list = solder . durations
2012-11-22 06:22:33 +00:00
self . constraint_model . reset ( )
2012-11-20 15:55:22 +00:00
ix = self . constraint_model . index ( 0 , 0 )
self . _constraint_selected ( ix )
2012-11-21 11:06:39 +00:00
self . constraint_view . setCurrentIndex ( ix )
2012-11-20 15:55:22 +00:00
def _constraint_selected ( self , index ) :
2012-11-21 11:06:39 +00:00
if index . isValid ( ) :
self . spinbox_block = True
temp_levels , value = self . constraint_model . constraint_list [ index . row ( ) ]
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . setTempLevels ( temp_levels )
2012-11-21 11:06:39 +00:00
self . controls . value . setValue ( value )
else :
self . spinbox_block = True
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . setTempLevels ( list ( ) )
2012-11-21 11:06:39 +00:00
self . controls . value . setValue ( 0 )
2012-11-22 06:23:50 +00:00
2012-11-21 11:06:39 +00:00
2012-11-22 18:59:40 +00:00
class RateConstraintWidget ( ConstraintWidget ) :
def _set_data ( self , solder ) :
self . spinbox_block = True
self . constraint_model . constraint_list = solder . rates
self . constraint_model . reset ( )
ix = self . constraint_model . index ( 0 , 0 )
self . _constraint_selected ( ix )
self . constraint_view . setCurrentIndex ( ix )
def _constraint_selected ( self , index ) :
if index . isValid ( ) :
self . spinbox_block = True
temp_levels , value = self . constraint_model . constraint_list [ index . row ( ) ]
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . setTempLevels ( temp_levels )
2012-11-22 18:59:40 +00:00
self . controls . value . setValue ( value )
else :
self . spinbox_block = True
2012-11-23 13:03:40 +00:00
self . selected_temp_levels_model . setTempLevels ( [ ] )
2012-11-22 18:59:40 +00:00
self . controls . value . setValue ( 0 )
2012-11-21 11:06:39 +00:00
class OvenControlsWidget ( QtGui . QWidget ) :
def __init__ ( self , parent = None ) :
super ( OvenControlsWidget , self ) . __init__ ( parent )
self . left = QtGui . QWidget ( self )
self . temp_lcd = QtGui . QLCDNumber ( self )
self . time_lcd = QtGui . QLCDNumber ( self )
self . time_lcd . setDigitCount ( 3 )
self . temp_lcd . setDigitCount ( 3 )
palette = QtGui . QPalette ( )
palette . setColor ( QtGui . QPalette . WindowText , QtCore . Qt . black )
self . temp_lcd . setPalette ( palette )
self . time_lcd . setPalette ( palette )
self . time_lcd . setSmallDecimalPoint ( False )
self . temp_lcd . setSmallDecimalPoint ( False )
self . temp_lcd . setSegmentStyle ( 2 )
self . time_lcd . setSegmentStyle ( 2 )
self . time_lcd . display ( " 000 " )
self . temp_lcd . display ( " 142 " )
self . temp_label = QtGui . QLabel ( " Time " , self )
self . time_label = QtGui . QLabel ( " Temp " , self )
self . temp_label . setBuddy ( self . temp_lcd )
self . time_label . setBuddy ( self . time_lcd )
self . sicon = QtGui . QIcon . fromTheme ( " media-playback-start " )
self . picon = QtGui . QIcon . fromTheme ( " media-playback-pause " )
self . start_button = QtGui . QPushButton ( self . sicon , " start " )
self . start_button . setCheckable ( True )
layout = QtGui . QHBoxLayout ( self . left )
layout . addWidget ( self . time_label )
layout . addWidget ( self . time_lcd )
layout . addWidget ( self . temp_label )
layout . addWidget ( self . temp_lcd )
layout . addWidget ( self . start_button )
layout2 = QtGui . QHBoxLayout ( )
self . temp_level_widget = TempLevelWidget ( self , True )
layout2 . addWidget ( self . temp_level_widget , 2 )
layout2 . addWidget ( self . left , 4 )
self . setLayout ( layout2 )
self . connect (
self . start_button ,
QtCore . SIGNAL ( " clicked() " ) ,
self . toggle_button )
def toggle_button ( self ) :
if self . start_button . isChecked ( ) :
self . start_button . setIcon ( self . picon )
else :
self . start_button . setIcon ( self . sicon )
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
class Report ( QtGui . QWidget ) :
def __init__ ( self , parent = None ) :
super ( Report , self ) . __init__ ( parent )
2012-11-23 13:03:40 +00:00
self . operator = QtGui . QLineEdit ( self )
self . date_begin = QtGui . QDateTimeEdit ( self )
self . date_end = QtGui . QDateTimeEdit ( self )
self . durations = list ( )
self . plot_file = " "
layout = QtGui . QGridLayout ( self )
layout . addWidget ( QtGui . QLabel ( " operator " ) , 0 , 0 )
layout . addWidget ( QtGui . QLabel ( " date begin " ) , 1 , 0 )
layout . addWidget ( QtGui . QLabel ( " date end " ) , 2 , 0 )
layout . addWidget ( self . operator , 0 , 1 )
layout . addWidget ( self . date_begin , 1 , 1 )
layout . addWidget ( self . date_end , 2 , 1 )
def export_pdf ( self ) :
pass
2012-11-18 14:14:17 +00:00
class ApplicationWindow ( QtGui . QMainWindow ) :
def __init__ ( self ) :
QtGui . QMainWindow . __init__ ( self )
2012-11-20 15:55:22 +00:00
self . dpi = 100
2012-11-18 14:14:17 +00:00
self . setAttribute ( QtCore . Qt . WA_DeleteOnClose )
self . setWindowTitle ( " application main window " )
self . file_menu = QtGui . QMenu ( ' &File ' , self )
2012-11-21 11:06:39 +00:00
self . file_menu . addAction ( ' &Create profile header ' , self . create_header ,
QtCore . Qt . CTRL + QtCore . Qt . Key_C )
2012-11-21 19:39:22 +00:00
self . file_menu . addAction ( ' &Save solder ' , self . save_solder ,
2012-11-18 14:14:17 +00:00
QtCore . Qt . CTRL + QtCore . Qt . Key_S )
2012-11-22 16:49:57 +00:00
self . file_menu . addAction ( ' &Reload solder ' , self . reload_solder ,
QtCore . Qt . CTRL + QtCore . Qt . Key_R )
self . file_menu . addAction ( ' &Delete solder ' , self . remove_solder ,
QtCore . Qt . CTRL + QtCore . Qt . Key_D )
2012-11-21 19:39:22 +00:00
self . file_menu . addAction ( ' S&ave plot ' , self . save_plot ,
QtCore . Qt . CTRL + QtCore . Qt . Key_A )
2012-11-23 13:03:40 +00:00
self . file_menu . addAction ( ' &Quit ' , self . show_report ,
QtCore . Qt . CTRL + QtCore . Qt . Key_T )
2012-11-21 11:06:39 +00:00
self . file_menu . addAction ( ' &Quit ' , self . fileQuit ,
QtCore . Qt . CTRL + QtCore . Qt . Key_Q )
2012-11-18 14:14:17 +00:00
self . menuBar ( ) . addMenu ( self . file_menu )
2012-11-21 11:06:39 +00:00
self . view_menu = QtGui . QMenu ( ' &View ' , self )
2012-11-21 19:39:22 +00:00
self . profile_view_action = self . view_menu . addAction ( " &Profile View " , self . open_profile_view ,
QtCore . Qt . CTRL + QtCore . Qt . Key_P )
self . controls_view_action = self . view_menu . addAction ( " &Oven Controls View " , self . open_controls_view ,
QtCore . Qt . CTRL + QtCore . Qt . Key_O )
2012-11-21 11:06:39 +00:00
self . view_group = QtGui . QActionGroup ( self )
self . view_group . setExclusive ( True )
self . view_group . addAction ( self . controls_view_action )
self . view_group . addAction ( self . profile_view_action )
self . profile_view_action . setCheckable ( True )
self . controls_view_action . setCheckable ( True )
2012-11-23 13:03:40 +00:00
self . report = Report ( self )
self . report . hide ( )
2012-11-21 19:39:22 +00:00
#self.connect(self.profile_view_action,
#QtCore.SIGNAL("triggered()"),
#self.open_profile_view)
2012-11-21 11:06:39 +00:00
2012-11-21 19:39:22 +00:00
#self.connect(self.controls_view_action,
#QtCore.SIGNAL("triggered()"),
#self.open_controls_view)
2012-11-21 11:06:39 +00:00
self . profile_view_action . setChecked ( True )
self . menuBar ( ) . addMenu ( self . view_menu )
2012-11-18 14:14:17 +00:00
self . help_menu = QtGui . QMenu ( ' &Help ' , self )
self . menuBar ( ) . addSeparator ( )
self . menuBar ( ) . addMenu ( self . help_menu )
self . help_menu . addAction ( ' &About ' , self . about )
2012-11-20 15:55:22 +00:00
self . tab_widget = QtGui . QTabWidget ( self )
2012-11-21 11:06:39 +00:00
self . temp_level_widget = TempLevelWidget ( self )
self . duration_widget = DurationConstraintWidget ( u " Duration (s) " )
self . rate_widget = RateConstraintWidget ( u " Rate (°C/s) " )
2012-11-22 16:49:57 +00:00
self . tab_widget . addTab ( self . temp_level_widget , u " Temperature Levels (°C) " )
2012-11-18 14:38:57 +00:00
self . tab_widget . addTab ( self . duration_widget , u " Duration (s) " )
self . tab_widget . addTab ( self . rate_widget , u " Rate (°C/s) " )
2012-11-21 11:06:39 +00:00
self . plotter = Plotter ( self , self , width = 5 , height = 4 , dpi = self . dpi )
self . controls_widget = OvenControlsWidget ( self )
self . controls_widget . setVisible ( False )
2012-11-21 19:39:22 +00:00
self . connect (
self . duration_widget ,
QtCore . SIGNAL ( " solder_changed() " ) ,
self . plotter . solder_changed )
self . connect (
self . rate_widget ,
QtCore . SIGNAL ( " solder_changed() " ) ,
self . plotter . solder_changed )
2012-11-20 15:55:22 +00:00
self . connect (
2012-11-21 19:39:22 +00:00
self . temp_level_widget ,
QtCore . SIGNAL ( " solder_changed() " ) ,
self . plotter . solder_changed )
2012-11-22 06:22:33 +00:00
self . connect (
self . duration_widget ,
QtCore . SIGNAL ( " solder_changed() " ) ,
self . plotter . solder_changed )
self . connect (
self . rate_widget ,
QtCore . SIGNAL ( " solder_changed() " ) ,
self . plotter . solder_changed )
2012-11-21 19:39:22 +00:00
self . solder_widget = SolderWidget ( self )
self . connect (
self . solder_widget . solder_view ,
2012-11-20 15:55:22 +00:00
QtCore . SIGNAL ( " clicked(QModelIndex) " ) ,
self . solder_selected )
2012-11-18 14:38:57 +00:00
2012-11-20 20:33:15 +00:00
2012-11-20 15:55:22 +00:00
self . settings_widget = QtGui . QWidget ( self )
pl = QtGui . QHBoxLayout ( self . settings_widget )
2012-11-21 19:39:22 +00:00
pl . addWidget ( self . solder_widget , 1 )
pl . addWidget ( self . tab_widget , 3 )
2012-11-21 11:06:39 +00:00
2012-11-20 15:55:22 +00:00
self . splitter = QtGui . QSplitter ( QtCore . Qt . Vertical , self )
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
self . plotter_splitter = QtGui . QSplitter ( self )
self . profile_log = QtGui . QTextEdit ( self )
2012-11-21 19:39:22 +00:00
self . solder_selected ( self . solder_widget . solder_model . index ( 0 , 0 ) )
2012-11-18 14:14:17 +00:00
2012-11-22 06:22:33 +00:00
self . plotter_splitter . addWidget ( self . plotter )
self . plotter_splitter . addWidget ( self . profile_log )
2012-11-20 15:55:22 +00:00
self . splitter . addWidget ( self . settings_widget )
2012-11-21 11:06:39 +00:00
self . splitter . addWidget ( self . controls_widget )
2012-11-22 06:22:33 +00:00
self . splitter . addWidget ( self . plotter_splitter )
2012-11-20 15:55:22 +00:00
self . splitter . setStretchFactor ( 0 , 2 )
2012-11-21 11:06:39 +00:00
self . splitter . setStretchFactor ( 1 , 2 )
self . splitter . setStretchFactor ( 2 , 8 )
2012-11-20 15:55:22 +00:00
self . setCentralWidget ( self . splitter )
2012-11-18 14:14:17 +00:00
2012-11-22 18:59:40 +00:00
self . statusBar ( ) . showMessage ( " Reflow GORE!1! " , 10000 )
2012-11-18 14:14:17 +00:00
2012-11-20 15:55:22 +00:00
self . temp_level_widget . temp_level_removed . connect ( self . duration_widget . slot_temp_level_removed )
self . temp_level_widget . temp_level_removed . connect ( self . rate_widget . slot_temp_level_removed )
2012-11-23 13:03:40 +00:00
self . temp_level_widget . temp_levels_changed . connect ( self . duration_widget . temp_levels_changed )
self . temp_level_widget . temp_levels_changed . connect ( self . rate_widget . temp_levels_changed )
2012-11-21 11:06:39 +00:00
def getPlotter ( self ) :
return self . plotter
def create_header ( self ) :
x_list = list ( )
y_list = list ( )
for solder in self . solder_model . listdata :
x , y , xmax , ymax , duration_points , rate_points = solder . calc_profile ( )
x_list . append ( x )
y_list . append ( y )
2012-11-22 06:23:50 +00:00
#print "packet", repr(create_profile_packet(x, y))
2012-11-21 11:06:39 +00:00
create_profile_header ( x_list , y_list )
2012-11-18 14:14:17 +00:00
def solder_selected ( self , index ) :
if index . isValid ( ) :
2012-11-21 19:39:22 +00:00
solder = self . solder_widget . solder_model . listdata [ index . row ( ) ]
2012-11-21 11:06:39 +00:00
self . temp_level_widget . setData ( solder )
2012-11-20 15:55:22 +00:00
self . duration_widget . setData ( solder )
self . rate_widget . setData ( solder )
2012-11-21 11:06:39 +00:00
self . plotter . setData ( solder )
self . controls_widget . temp_level_widget . setData ( solder )
2012-11-22 06:22:33 +00:00
solder . log_message . connect ( self . profile_log . setPlainText )
2012-11-21 11:06:39 +00:00
2012-11-22 16:49:57 +00:00
def remove_solder ( self ) :
2012-11-22 18:59:40 +00:00
self . solder_selected ( self . solder_widget . remove_solder ( ) )
2012-11-22 16:49:57 +00:00
2012-11-21 11:06:39 +00:00
def open_controls_view ( self ) :
self . controls_widget . show ( )
self . settings_widget . hide ( )
def open_profile_view ( self ) :
self . controls_widget . hide ( )
self . settings_widget . show ( )
2012-11-18 14:14:17 +00:00
2012-11-23 13:03:40 +00:00
def show_report ( self ) :
self . report . exec ( )
2012-11-18 14:14:17 +00:00
def save_plot ( self ) :
file_choices = " PNG (*.png)|*.png "
filename = QtGui . QFileDialog . getSaveFileName ( self , ' Save File ' , ' qtplot.png ' )
2012-11-20 15:55:22 +00:00
self . plotter . print_figure ( str ( filename ) , dpi = self . dpi )
2012-11-18 14:14:17 +00:00
2012-11-21 19:39:22 +00:00
def save_solder ( self ) :
2012-11-22 16:49:57 +00:00
self . plotter . solder . save ( )
2012-11-23 13:03:40 +00:00
self . solder_widget . solder_model . listdata . sort ( key = lambda x : x . name )
2012-11-22 18:59:40 +00:00
self . solder_widget . solder_model . reset ( )
new_index = self . solder_widget . solder_model . index ( self . solder_widget . solder_model . listdata . index ( self . plotter . solder ) )
self . solder_widget . solder_view . setCurrentIndex ( new_index )
2012-11-21 19:39:22 +00:00
2012-11-22 16:49:57 +00:00
def reload_solder ( self ) :
old_index = self . solder_widget . solder_view . currentIndex ( )
solder = Solder . unpack ( self . plotter . solder . filename , self . solder_widget . solder_model )
self . solder_widget . solder_model . listdata [ old_index . row ( ) ] = solder
self . solder_widget . solder_model . reset ( )
new_index = self . solder_widget . solder_model . index ( old_index . row ( ) , 0 )
self . solder_widget . solder_view . setCurrentIndex ( new_index )
self . solder_selected ( new_index )
2012-11-18 14:14:17 +00:00
def fileQuit ( self ) :
self . close ( )
def closeEvent ( self , ce ) :
self . fileQuit ( )
def about ( self ) :
QtGui . QMessageBox . about ( self , " About %s " % progname ,
2012-11-22 18:59:40 +00:00
QtCore . QString ( u " <html> %(prog)s version %(version)s <br/>Copyright \N{COPYRIGHT SIGN} 2012 Stefan Kögl<br/><br/>reflowctl frontend<br/><br/>Special thanks to <a href= ' http://www.chaostreff-dortmund.de/ ' >Chaostreff Dortmund</a></html> " % { " prog " : progname , " version " : progversion } ) )
2012-11-18 14:14:17 +00:00
def main ( ) :
2012-11-22 16:49:57 +00:00
# numpy bug workaround
try :
numpy . log10 ( 0.0 )
except :
pass
2012-11-18 14:14:17 +00:00
qApp = QtGui . QApplication ( sys . argv )
aw = ApplicationWindow ( )
aw . setWindowTitle ( " %s " % progname )
aw . show ( )
sys . exit ( qApp . exec_ ( ) )
2012-11-23 13:03:40 +00:00
#if __name__ == '__main__':
#main()
tls = [ TempLevel ( ' peak ' , 260 ) , TempLevel ( ' environment temp ' , 20.0 ) ]
a = TempLevel ( ' tal ' , 200 )
print a . is_between ( * tls )