Example #1
0
    def __init__( self, basedir ):
        self.builder = gtk.Builder()
        self.builder.add_from_file( builder_file ) 
        
        self.config = TermoConfig( basedir + "config.db" )
        
        self.mode = self.config.get( "mode", default_mode )
        self.builder.get_object( "radio%s" % self.mode ).set_active( True )
        
        self.scales = []
        for i in range( 24 ):
            scale = self.builder.get_object( "vscale%s" % i )
            scale.set_value( self.config.get( "temp_%s" % i, 0 ) )
            self.scales.append( scale )
        
        self.builder.connect_signals( self )
        
        # collegati alla caldaia
        self.switch = TermoSwitch()
        self.update_switch_ui()
    
        # crea il thread del termometro
        # specifica la callback
        self.feed = TermoFeed( self.got_point )
        self.feed.start()
        
        # apre/crea lo storico
        self.storico = TermoStory( basedir + "storico.db" )
        
        # crea il grafico
        self.figure = Figure()
        self.canvas = FigureCanvas( self.figure )
        
        # crea asse temperatura
        self.temp_axes = self.figure.add_subplot( 111 )
        self.temp_axes.xaxis.set_major_locator( matplotlib.dates.HourLocator() )
        self.temp_axes.xaxis.set_minor_locator( matplotlib.dates.MinuteLocator() )
        self.temp_axes.xaxis.set_major_formatter( matplotlib.dates.DateFormatter( '%H' ) )
        self.temp_axes.set_ylabel( u"Temperatura", color="m" )
        self.temp_axes.yaxis.set_major_formatter( temp_formatter )
        self.temp_axes.grid( True )
        
        # crea asse umidita
        self.umid_axes = self.temp_axes.twinx()
        self.umid_axes.xaxis.set_major_locator( matplotlib.dates.HourLocator() )
        self.umid_axes.xaxis.set_minor_locator( matplotlib.dates.MinuteLocator() )
        self.umid_axes.xaxis.set_major_formatter( matplotlib.dates.DateFormatter( '%H' ) )
        self.umid_axes.set_ylabel( u"Umidità", color= "c" )
        self.umid_axes.yaxis.set_major_formatter( umid_formatter )
        self.umid_axes.grid( True )

        # crea linee
        self.temp_line = self.temp_axes.plot( [], [], "m" )[0]
        self.umid_line = self.umid_axes.plot( [], [], "c", alpha=0.5 )[0]
        self.switch_collection = None
        
        self.update_plot()

        hbox2 = self.builder.get_object( "hbox2" )
        hbox2.add( self.canvas )

        # partiamo
        self.builder.get_object( "window1" ).show_all()
Example #2
0
class TermoGUI( object ):
    def __init__( self, basedir ):
        self.builder = gtk.Builder()
        self.builder.add_from_file( builder_file ) 
        
        self.config = TermoConfig( basedir + "config.db" )
        
        self.mode = self.config.get( "mode", default_mode )
        self.builder.get_object( "radio%s" % self.mode ).set_active( True )
        
        self.scales = []
        for i in range( 24 ):
            scale = self.builder.get_object( "vscale%s" % i )
            scale.set_value( self.config.get( "temp_%s" % i, 0 ) )
            self.scales.append( scale )
        
        self.builder.connect_signals( self )
        
        # collegati alla caldaia
        self.switch = TermoSwitch()
        self.update_switch_ui()
    
        # crea il thread del termometro
        # specifica la callback
        self.feed = TermoFeed( self.got_point )
        self.feed.start()
        
        # apre/crea lo storico
        self.storico = TermoStory( basedir + "storico.db" )
        
        # crea il grafico
        self.figure = Figure()
        self.canvas = FigureCanvas( self.figure )
        
        # crea asse temperatura
        self.temp_axes = self.figure.add_subplot( 111 )
        self.temp_axes.xaxis.set_major_locator( matplotlib.dates.HourLocator() )
        self.temp_axes.xaxis.set_minor_locator( matplotlib.dates.MinuteLocator() )
        self.temp_axes.xaxis.set_major_formatter( matplotlib.dates.DateFormatter( '%H' ) )
        self.temp_axes.set_ylabel( u"Temperatura", color="m" )
        self.temp_axes.yaxis.set_major_formatter( temp_formatter )
        self.temp_axes.grid( True )
        
        # crea asse umidita
        self.umid_axes = self.temp_axes.twinx()
        self.umid_axes.xaxis.set_major_locator( matplotlib.dates.HourLocator() )
        self.umid_axes.xaxis.set_minor_locator( matplotlib.dates.MinuteLocator() )
        self.umid_axes.xaxis.set_major_formatter( matplotlib.dates.DateFormatter( '%H' ) )
        self.umid_axes.set_ylabel( u"Umidità", color= "c" )
        self.umid_axes.yaxis.set_major_formatter( umid_formatter )
        self.umid_axes.grid( True )

        # crea linee
        self.temp_line = self.temp_axes.plot( [], [], "m" )[0]
        self.umid_line = self.umid_axes.plot( [], [], "c", alpha=0.5 )[0]
        self.switch_collection = None
        
        self.update_plot()

        hbox2 = self.builder.get_object( "hbox2" )
        hbox2.add( self.canvas )

        # partiamo
        self.builder.get_object( "window1" ).show_all()

    def on_mode_toggled( self, radio ):
        """ è stata cambiata la modalità..
        """
        for mode in modes:
            radio = self.builder.get_object( "radio%s" % mode )
            if radio.get_active():
                self.mode = mode
                self.config.set( "mode", mode )
                break
        # impostato su acceso/spento -> spegniamo/accendiamo il riscaldamento
        if mode == "acceso":
            self.switch.set_state( True )
        elif mode == "spento":
            self.switch.set_state( False )

    def on_vscale_value_changed( self, scale ):
        """ uno degli slider è stato spostato..
        """
        for idx, obj in enumerate( self.scales ):
            if obj == scale:
                self.config.set( "temp_%s" % idx, scale.get_value() )
                break
        else:
            raise Exception( "VScale non trovato" )

    def got_point( self, temp, umid ):
        """ abbiamo ricevuto una misurazione dal termometro..
        """
        # popola lo storico
        self.storico.add( temp, umid, self.switch.get_state() )
        
        # pilota la caldaia..
        if self.mode == "programmato":
            hh = datetime.datetime.now().hour
            temp_prog = self.config.get( "temp_%s" % hh, 0 )
            
            # versione grezza
            # temperatura attuale +- tolleranza -> attacca e stacca
            # utilizziamo solo la sicurezza interna dello switch
            if temp < temp_prog - tolleranza:
                self.switch.set_state( True )
            elif temp > temp_prog + tolleranza:
                self.switch.set_state( False )
        elif self.mode == "acceso":
            self.switch.set_state( True )
        elif self.mode == "spento":
            self.switch.set_state( False )
            
        # aggiorna la UI
        self.update_temp_umid( temp, umid )
        self.update_switch_ui()
    
    def update_switch_ui( self ):
        """ leggi lo stato dello switch e aggiorna la UI
        """
        label = self.builder.get_object( "label_switch" )
        state = self.switch.get_state() 
        if state == None:
            label.set_text( "N/A" )
        elif state:
            label.set_text( "Il riscaldamento è ACCESO" )
        else:
            label.set_text( "Il riscaldamento è SPENTO" )

    def update_plot( self ):
        """ leggi lo storico e aggiorna i grafici
        """
        dmax = datetime.datetime.now() + graph_margin
        dmin = dmax - ( graph_width + graph_margin )
        dates, temp, umid, switch = self.storico.search( dmin, dmax )

        mpldates = [ matplotlib.dates.date2num( date ) for date in dates ]
        mpldmin = matplotlib.dates.date2num( dmin )
        mpldmax = matplotlib.dates.date2num( dmax )
        
        if temp:
            # grafico delle temperature
            mintemp = min(temp)*0.999
            maxtemp = max(temp)*1.001
            self.temp_line.set_data( mpldates, temp )
            self.temp_axes.set_ylim( mintemp, maxtemp )
            self.temp_axes.set_xlim( mpldmin, mpldmax )
            
            # span della caldaia
            if self.switch_collection:
                self.switch_collection.remove()    
            self.switch_collection = matplotlib.collections.BrokenBarHCollection.span_where(
                mpldates, ymin=mintemp, ymax=maxtemp, where=switch, facecolor='red', alpha=0.1, linewidths=0 )
            self.temp_axes.add_collection( self.switch_collection )
            
        if umid:
            # grafico delle umidita (asse x condivisa)
            minumid = min(umid)*0.999
            maxumid = max(umid)*1.001
            self.umid_line.set_data( mpldates, umid )
            self.umid_axes.set_ylim( minumid, maxumid )
            self.umid_axes.set_xlim( mpldmin, mpldmax )
        
        self.canvas.draw()
        
    def update_temp_umid( self, temp, umid ):
        """ aggiorna le label della temperatura e umidità attuali
        """
        gtk.gdk.threads_enter()
        self.builder.get_object( "label_temp" ).set_text( fmt_temp( temp ) )
        self.builder.get_object( "label_umid" ).set_text( fmt_umid( umid ) )
        self.update_plot()        
        gtk.gdk.threads_leave()

    def on_window1_destroy( self, widget, data=None ):
        """ uscita dal programma
        """
        self.storico.save()
        self.config.save()
        self.feed.stop()
        gtk.main_quit()