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) + '$'