Exemplo n.º 1
0
class DrawPlot(BoxLayout):

    def draw_my_plot(self):
        self.figure_1 = Figure(figsize=(2, 2))
        self.figure_1.subplots_adjust(left=0.13, right=0.93, bottom=0.25,
                                      top=0.98)  # to expand and occupy full area around imshow
        #self.panel_col = (1,0,0)
        self.x_vals = np.arange(0, 10, 0.01)
        self.y_vals = np.zeros(len(self.x_vals))
        #self.figure_1.set_facecolor(self.rgb_to_hex(self.panel_col))
        self.axes = self.figure_1.add_subplot(111)
        self.canvas_speech = FigureCanvas(self.figure_1)
        self.axes.set_xlim(0, 10)
        self.axes.set_ylim(-1, 1)


        #self.axes.set_facecolor(self.rgb_to_hex(self.panel_col))
        self.axes.grid(True, color='lightgray')
        #self.axes.xaxis.set_major_formatter(FormatStrFormatter('%.1f'))
        self.axes.set_xlabel('Time (s)', fontsize=10, labelpad=0)
        self.axes.set_ylabel('Signal (norm)', fontsize=10, labelpad=0)
        self.line11, = self.axes.plot(self.x_vals, self.y_vals, "b", linewidth=0.5)



        self.axes.plot(self.x_vals, self.y_vals, "b", linewidth=0.5)
        self.canvas_speech.draw_idle()
        #self.canvas_speech.Refresh()

        # Draw 2 line on speech graph
        self.line_a = lines.Line2D((0.25, 0.25), (-1, 1), picker=5, color="r", linewidth=2)
        self.line_b = lines.Line2D((9.75, 9.75), (-1, 1), picker=5, color="r", linewidth=2)
        self.a_point = 0.25
        self.b_point = 9.75
        self.draggable_line_a(self.line_a, self.axes)
        self.draggable_line_b(self.line_b, self.axes)

        self.axes.add_line(self.line_a)
        self.axes.add_line(self.line_b)


        self.add_widget(self.canvas_speech, 1) #<==== This adds a graph above the first row (index=1)

    def draggable_line_a(self, line_a, ax):
        self.line_a = line_a
        self.c_a = ax.get_figure().canvas
        self.sid_a = self.c_a.mpl_connect('pick_event', self.clickonline_a)

    def draggable_line_b(self, line_b, ax):
        self.line_b = line_b
        self.c_b = ax.get_figure().canvas
        self.sid_b = self.c_b.mpl_connect('pick_event', self.clickonline_b)
    def clickonline_a(self, event):
        # pub.sendMessage("SELECT_CHANGE", value=None)
        if event.artist == self.line_a:
            self.foll_a = self.c_a.mpl_connect("motion_notify_event", self.followmouse_a)
            self.rel_a = self.c_a.mpl_connect("button_release_event", self.releaseonclick_a)

    def clickonline_b(self, event):
        # pub.sendMessage("SELECT_CHANGE", value=None)
        if event.artist == self.line_b:
            self.foll_b = self.c_b.mpl_connect("motion_notify_event", self.followmouse_b)
            self.rel_b = self.c_b.mpl_connect("button_release_event", self.releaseonclick_b)

    def followmouse_a(self, event):
        if event.inaxes is None:
            return
        if event.button != 1:
            return
        self.line_a.set_xdata(event.xdata)
        self.c_a.draw_idle()

    def followmouse_b(self, event):
        if event.inaxes is None:
            return
        if event.button != 1:
            return
        self.line_b.set_xdata(event.xdata)
        self.c_b.draw_idle()
    def releaseonclick_a(self, event):
        self.a_point = self.line_a.get_xdata()
        if round(self.b_point,2) - round(self.a_point,2) < 0.16:
            b_minus_a=round(self.b_point, 2) - round(self.a_point, 2)
            minus_val=0.20-b_minus_a
            self.line_a.set_xdata(self.a_point-minus_val)
            self.a_point = self.line_a.get_xdata()
            self.c_a.draw_idle()
        self.c_a.mpl_disconnect(self.rel_a)

        self.c_a.mpl_disconnect(self.foll_a)
        print(self.line_a.get_xdata())
    def releaseonclick_b(self, event):
        self.b_point = self.line_b.get_xdata()
        if round(self.b_point,2) - round(self.a_point,2) < 0.16:
            b_minus_a=round(self.b_point, 2) - round(self.a_point, 2)
            minus_val=0.20-b_minus_a
            self.line_b.set_xdata(self.b_point+minus_val)
            self.b_point = self.line_b.get_xdata()
            self.c_b.draw_idle()
        self.c_b.mpl_disconnect(self.rel_b)
        self.c_b.mpl_disconnect(self.foll_b)
class EVScreen(Screen):
    charging = False
    isCharging = False
    turn_on = [0x58,0x90]
    turn_off = [0x58,0x99]
    recieve = [0x58,0x00]
    dr_override = False
    isoverride = False
    price =[0]
    currvolt=[0,0]
    power = 0
    dailyusage = []
    powerconsumption = np.zeros(1440)
    totalCost =0
    totalEnergy = 0
    priceperMin = np.zeros(1440)
    
    #################################################################################
    # Name: __init__                                                                #
    # Parameters: self                                                              #
    # Description: This method initialises EV Screen Class                          #
    #                                                                               #
    # Preconditions: n/a                                                            #
    # Postconditions: n/a                                                           #
    #################################################################################
    def __init__(self, **kwargs):
        Screen.__init__(self, **kwargs)
        self.price_power_fig, self.price_plot = plt.subplots()
        self.consumption_plot = self.price_power_fig.add_subplot(111, sharex=self.price_plot, frameon=False)
        self.price_power_canvas = FigureCanvasKivyAgg(figure=self.price_power_fig)
        self.pricepwrPlot()
        self.xbee = xbee.Xbee("/dev/ttyS0")
        self.ids.consdata.add_widget(self.price_power_canvas)
        self.totalMonthconsumptionPlot()
        self.ids.monthly.add_widget(FigureCanvasKivyAgg(plt.gcf()))
        Clock.schedule_interval(self.evCharging, 0.5)
        Clock.schedule_interval(self.get_power, 0.7)
        Clock.schedule_interval(self.calCost, 1)
        Clock.schedule_interval(self.pricepwrPlot, 15)
    
    #################################################################################
    # Name: evcharging                                                              #
    # Parameters: self                                                              #
    # Description: This method implements the EV charging control                   #
    #                                                                               #
    # Preconditions: n/a                                                            #
    # Postconditions: n/a                                                           #
    #################################################################################
    def evCharging(self, *args):
        minutes = self.manager.get_screen("Home").minutes
        is_scheduled = self.manager.get_screen("sched").is_scheduled
        load_profile = self.manager.get_screen("sched").load_profile
        p_rated = self.manager.get_screen("sched").p_rated
        tou = self.manager.get_screen("Home").timeofusedata
        if(tou != 0):
            self.price = tou[2]
            self.priceperMin = tou[3]
        
        
        if (self.dr_override == True) and (self.charging == False):
            self.dr_override = False
            self.xbee.send(data=self.turn_on)
            self.charging = True
            self.ids.charge.text = 'Charging'
            self.ids.overide.text = 'Turn Off'
            if(is_scheduled == True):
                self.isoverride = True
            
        
        if (self.dr_override == True) and (self.charging == True):
            self.dr_override = False
            self.xbee.send(data=self.turn_off)
            self.charging = False
            self.ids.charge.text = 'Not Charging'
            self.ids.overide.text = 'Turn On'
            if(is_scheduled == True):
                self.isoverride = True
          
        
        if ((is_scheduled == True) and (self.isoverride == False)):
            if (minutes%15 == 0):
                i = int(minutes/15)
                print(minutes)
                print(i)
                if (i != 96): 
                    if ((load_profile[i] > 5) and (self.charging == False)):
                        print(int(load_profile[i]))
                        self.xbee.send(self.turn_on)
                        self.charging = True
                        self.ids.charge.text = 'Charging'
                        self.ids.overide.text = 'Turn Off'
                    
                    elif ((load_profile[i] < 5) and (self.charging == True)):
                        print(int(load_profile[i]))
                        self.xbee.send(self.turn_off)
                        self.charging = False
                        self.ids.charge.text = 'Not Charging'
                        self.ids.overide.text = 'Turn On'
                

                    
    
    #################################################################################
    # Name: pricepwrplot                                                            #
    # Parameters: self                                                              #
    # Description: This method plot price and power consumption data                #
    #                                                                               #
    # Preconditions: n/a                                                            #
    # Postconditions: n/a                                                           #
    # Reference for customizing plot:                                               #
    # https://stackoverflow.com/questions/14908576                                  #
    # /how-to-remove-frame-from-matplotlib-pyplot-figure-vs-matplotlib-figure-frame #
    #################################################################################
    def pricepwrPlot(self, *args):
        if (len(self.dailyusage) == 96):
            self.dailyusage = []

            self.consumption_plot.remove()
            self.consumption_plot = self.price_power_fig.add_subplot(111, sharex=self.price_plot, frameon=False)
            self.totalCost = 0
            self.totalEnergy = 0
            
            
        self.dailyusage.append(self.power)
        self.price_plot.plot(self.price, color='orange', linewidth=2, label= 'Price')
        x_skip = 4;
        n = 96
        min_per_k = 1440/n
        plt.xticks(np.arange(0, n+1, step=x_skip*(60/min_per_k)), np.arange(0, 25, step=x_skip))
        self.consumption_plot.plot(self.dailyusage, color = '#4c8a4c', linewidth=2, label='Power Consumption')
        self.consumption_plot.yaxis.tick_right()

        
        self.price_plot.spines['top'].set_visible(False)
        self.price_plot.spines['right'].set_visible(False)
        self.price_plot.spines['bottom'].set_visible(False)
        self.price_plot.spines['left'].set_visible(False)
        self.price_plot.yaxis.grid(True)
        self.price_plot.tick_params(top='off', bottom='off', left='off', right='off', labelleft='on', labelbottom='on')
        self.consumption_plot.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')
        self.consumption_plot.set_ylim(ymin=0, ymax= 2.5)
        self.price_power_canvas.draw_idle()
        
        
    #################################################################################
    # Name: totalMonthconsumptionPlot                                               #
    # Parameters: self                                                              #
    # Description: This method plots mothly power consumption data                  #
    #                                                                               #
    # Preconditions: n/a                                                            #
    # Postconditions: n/a                                                           #
    #################################################################################
    def totalMonthconsumptionPlot(self, *args):
        plt.figure()
        
        Month = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
        Energy = [50,30,40,45,50,65,60,43,23,40,11,
                  50,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        
        position = np.arange(len(Month))
        
        mybars = plt.bar(position, Energy, align ='center', linewidth =0)
        plt.xticks(position, Month)
        
        plt.title('Monthly')
        
        for spine in plt.gca().spines.values():
            spine.set_visible(False)
            
        plt.tick_params(top='off', bottom='off', left='off', right='off', labelleft='off', labelbottom='on')
        
        for bari in mybars:
            height = bari.get_height()
            plt.gca().text(bari.get_x() + bari.get_width()/2, bari.get_height()- 0.2, str(int(height)),
                           ha='center', color='white', fontsize=5)

    #################################################################################
    # Name: get_power                                                               #
    # Parameters: self                                                              #
    # Description: This method retrieve xbee queue data                             #
    #                                                                               #
    # Preconditions: n/a                                                            #
    # Postconditions: n/a                                                           #
    #################################################################################
    def get_power(self, dt=1):
        self.currvolt = self.xbee.recieve()
           
        if (self.currvolt != 0):
            print(self.currvolt)
            currtemp = self.currvolt[0]/1000
            volttemp = self.currvolt[1]/1000
        
            current = 28.123*(currtemp) + 0.0517
            voltage = 177.13*(volttemp**3) -  138.54*(volttemp**2) + 118.35*(volttemp) + 0.0193
            self.power = (current*voltage)/1000
            self.power = round(self.power, 2)
            print(self.power)
            self.ids.powerdis.text = '\r\r\r Live Usage: \n' + '      ' + str(self.power) + 'kW'

    #################################################################################
    # Name: calCost                                                                 #
    # Parameters: self                                                              #
    # Description: This method calculates total cost and total energy consumed      #
    #                                                                               #
    # Preconditions: n/a                                                            #
    # Postconditions: n/a                                                           #
    #################################################################################
    def calCost(self, *args):
        minutes = self.manager.get_screen("Home").minutes
        self.powerconsumption[minutes-1] = self.power
        self.totalCost = np.sum(self.powerconsumption*self.priceperMin)/60
        self.totalEnergy =np.sum(self.powerconsumption)/60
        self.totalCost = round(self.totalCost, 2)
        self.totalEnergy = round(self.totalEnergy, 2)
        self.ids.tusage.text = 'Total Usage: ' + str(self.totalEnergy) + 'kWh'
        self.ids.tcost.text = 'Total Cost: ' + str(self.totalCost) + '$'