src/digitemp/python/gui/dtgraph.py
#!/usr/bin/env python
# --------------------------------------------------------------------------
# 07/13/2003 The background needs to be drawn when starting up, it isn't
# bcl white. Need to record all the points so that the display can
# be redrawn when another window uncovers it.
# Add Glade dialog boxes to it for managing the sensors, their
# names and colors.
#
# When new data is read it needs to be added to an array of
# points (for each sensor). The array is then plotted using the
# points or line segment graphing functions. Hmm, should the
# reading be saved, and points regenerated? This allows for window
# resizing without losing any of the historical data.
#
# I also need to draw a background.
#
# Dictionary of serial numbers, names and colors
# Dictionary of serial numbers, array of sensor readings
#
# Add to the serial number list in the dt dictionary
# dt[serial#].append( value )
#
# How much data should be stored? I can always slice on the end
# of the list based on the display width, but I don't want to
# fill up memory by never removing old data.
#
# 07/12/2003 Second attempt at a PythonGTK DigiTemp live graphing app.
# bcl
# --------------------------------------------------------------------------
import os
import gtk
import time
import string
import operator
import sys
class DigiTempGraph:
min_temp = 0
max_temp = 40
readtemp_timer = 0
last_y = 0
# Sensor serial # and Temperature List
dt = {}
# Sensor serial # and name, color info
sensors = {}
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("DigiTemp Graph")
window.connect("destroy", gtk.mainquit)
self.area = gtk.DrawingArea()
self.area.set_size_request(400, 200)
self.pangolayout = self.area.create_pango_layout("")
window.add(self.area)
self.area.connect("expose-event", self.area_expose_cb)
self.area.show()
# Setup the colors to be used
self.colormap = window.get_colormap()
self.white = self.colormap.alloc_color( "white" )
self.black = self.colormap.alloc_color( "black" )
window.show()
# Start reading the temperature every ? seconds
self.init_sensors()
readtemp_timer = gtk.timeout_add( 1000, self.readtemp)
def area_expose_cb(self, area, event):
self.style = self.area.get_style()
self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
# Redraw the window, something has uncovered it
return gtk.TRUE
# Initalize the 1-wire network, print out whatever it says
def init_sensors( self ):
cmd = "/home/bcl/digitemp/digitemp -s/dev/ttyUSB0 -i -q -o\"T %R %N %.2C\" -O\"C %R %N %n %C\""
for outline in os.popen(cmd).readlines():
outline = outline[:-1];
# print outline
S = string.split( outline, ": " )
# print S[0]
# print S[1]
# Setup the sensor dictionary with an empty list
if( S[0][0:3] == 'ROM' ):
self.dt[S[1]] = []
self.sensors[S[1]] = [ S[1], "black" ]
# print "Added ",S[1]," to the dictionary\n"
# Ought to be able to check return code for success/failure
# Read all attached sensors
def read_sensors( self ):
cmd = "/home/bcl/digitemp/digitemp -a -q -o1"
for outline in os.popen(cmd).readlines():
outline = outline[:-1]
# print outline
S = string.split( outline, " " )
if S[0] == 'T':
value = string.atof(S[3])
# Add the temperature reading to a dictionary
self.dt[S[1]].append( value )
# Try to auto-size the graph
if( value > self.max_temp ):
self.max_temp = value + 5
if( value < self.min_temp ):
self.min_temp = value - 5
if S[0] == 'C':
value = string.atoi( S[3] )
# Add the counter reading to a dictionary
self.dt[S[1]].append( value )
# Should return the digitemp return code
return 1
# Read the temperature from the attached DigiTemp system
# and plot the new temperatures
def readtemp( self ):
global readtemp_timer
if( self.read_sensors() == 1 ):
for sensor in self.dt:
# print self.dt[sensor]
self.plottemp( sensor, self.dt[sensor] )
# Restart the timer
readtemp_timer = gtk.timeout_add( 1000, self.readtemp)
# Plot the temperatures in the drawing area
def plottemp( self, sensor, temperature ):
(width, height) = self.area.window.get_size()
# Scroll the display to the left
self.area.window.draw_drawable( self.gc, self.area.window, 1, 0, 0, 0, width-1, height)
# Erase the pixel just copied over
self.gc.set_foreground( self.white )
self.area.window.draw_point(self.gc, width-1, self.last_y)
# Plot the new temperature
self.gc.set_foreground( self.black )
temp_y = height - int(temperature * (height / (self.max_temp-self.min_temp)))
self.area.window.draw_point(self.gc, width-1, temp_y)
self.last_y = temp_y
def main():
gtk.main()
return 0
if __name__ == "__main__":
DigiTempGraph()
main()