def generate_schedule_charts(self, *args): """Generates the preview for the weekday and weekend rate schedule charts.""" weekday_schedule_data = self.rate_structure_selected['energy rate structure'].get('weekday schedule', []) weekend_schedule_data = self.rate_structure_selected['energy rate structure'].get('weekend schedule', []) legend_labels = ['${0}/kWh'.format(v) for _,v in self.rate_structure_selected['energy rate structure'].get('energy rates').items()] if weekday_schedule_data and weekend_schedule_data: n_tiers = len(np.unique(weekday_schedule_data)) palette = [rgba_to_fraction(color) for color in PALETTE][:n_tiers] labels = calendar.month_abbr[1:] self.energy_weekday_chart.draw_chart(np.array(weekday_schedule_data), palette, labels, legend_labels=legend_labels) self.energy_weekend_chart.draw_chart(np.array(weekend_schedule_data), palette, labels, legend_labels=legend_labels) weekday_schedule_data = self.rate_structure_selected['demand rate structure'].get('weekday schedule', []) weekend_schedule_data = self.rate_structure_selected['demand rate structure'].get('weekend schedule', []) legend_labels = ['${0}/kW'.format(v) for _,v in self.rate_structure_selected['demand rate structure'].get('time of use rates').items()] if weekday_schedule_data and weekend_schedule_data: n_tiers = len(np.unique(weekday_schedule_data)) # Select chart colors. palette = [rgba_to_fraction(color) for color in PALETTE][:n_tiers] labels = calendar.month_abbr[1:] # Draw charts. self.demand_weekday_chart.draw_chart(np.array(weekday_schedule_data), palette, labels, legend_labels=legend_labels) self.demand_weekend_chart.draw_chart(np.array(weekend_schedule_data), palette, labels, legend_labels=legend_labels)
def generate_demand_charge_comparison_chart(self, *args): """Generates the multiset bar chart comparing total demand charges with and without energy storage each month.""" if any(op[1].has_demand_charges() for op in self.chart_data): n_cats = 2 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) multisetbar_data = OrderedDict() for ix, op in enumerate(self.chart_data, start=0): name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] results = solved_op.results bar_group = [[ 'without ES', rgba_to_fraction(colors[0]), float(solved_op.demand_charge_without_es) ]] bar_group.append([ 'with ES', rgba_to_fraction(colors[1]), float(solved_op.demand_charge_with_es) ]) multisetbar_data[label] = bar_group self.chart.draw_chart(multisetbar_data) self.title.text = "Here are the demand charge totals each month." self.desc.text = 'The demand charge total consists of time-of-use peak demand charges in addition to a flat peak demand charge, if applicable. The time-of-use demand charge is based on the peak demand during each time period and the corresponding rate. The flat demand charge is based on the peak demand over the entire month, sometimes subject to minimum and/or maximum values. The ESS is useful for reducing net power draw during high time-of-use rates. ' report_templates = [] total_demand_charge_difference = sum(op[1].demand_charge_with_es - op[1].demand_charge_without_es for op in self.chart_data) if total_demand_charge_difference < 0: relation = 'decrease' total_difference_str = "It looks like the ESS was able to [b]{0}[/b] the total demand charges over the year by [b]{1}[/b].".format( relation, format_dollar_string(abs(total_demand_charge_difference))) report_templates.append(total_difference_str) self.desc.text += ' '.join(report_templates) self.is_drawn = True else: self.title.text = "It looks like there were no demand charges." self.desc.text = "The particular rate structure you selected resulted in no demand charges. Either there are no demand charges or no savings on demand charges were accrued using energy storage."
def on_imported_data_selected(self, instance, value): if value: self.open_data_importer_button.text = 'Data imported' self.open_data_importer_button.background_color = rgba_to_fraction(PALETTE[3]) Clock.schedule_once(partial(slow_blinking_animation, self.open_data_importer_button), 0) self.pv_profile_rv.deselect_all_nodes() else: self.open_data_importer_button.text = 'Open data importer' self.open_data_importer_button.background_color = rgba_to_fraction(PALETTE[0]) self.open_data_importer_button.opacity = 1 Animation.cancel_all(self.open_data_importer_button, 'opacity')
def generate_nem_charge_comparison_chart(self, *args): """Generates the multiset bar chart comparing total net energy metering charges with and without energy storage each month.""" if any(op[1].has_nem_charges() for op in self.chart_data): n_cats = 2 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) multisetbar_data = OrderedDict() for ix, op in enumerate(self.chart_data, start=0): name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] bar_group = [['without ES', rgba_to_fraction(colors[0]), float(solved_op.nem_charge_without_es)]] bar_group.append(['with ES', rgba_to_fraction(colors[1]), float(solved_op.nem_charge_with_es)]) multisetbar_data[label] = bar_group self.chart.draw_chart(multisetbar_data) self.title.text = "Here are the net energy metering (NEM) totals each month." net_metering_type = self.chart_data[0][1].nem_type net_metering_rate = self.chart_data[0][1].nem_rate if net_metering_type == 2: net_metering_type_str = '[b]Net energy metering 2.0[/b] uses the time-of-use energy rate for energy.' else: net_metering_type_str = '[b]Net energy metering 1.0[/b] uses a fixed price for energy, which was [b]{0}[/b]/kWh.'.format(format_dollar_string(net_metering_rate)) self.desc.text = "{0} Negative values represent credits. ".format(net_metering_type_str) report_templates = [ ] total_nem_difference = sum(op[1].nem_charge_with_es - op[1].nem_charge_without_es for op in self.chart_data) relation = 'increase' if total_nem_difference < 0 else 'decrease' total_difference_str = "The total [b]{0}[/b] in NEM credits with energy storage was [b]{1}[/b].".format(relation, format_dollar_string(abs(total_nem_difference))) report_templates.append(total_difference_str) self.desc.text += ' '.join(report_templates) self.is_drawn = True else: self.title.text = "It looks like there were no net energy metering charges or credits." self.desc.text = "The particular rate structure you selected resulted in no net energy metering charges. Either that or no savings on net energy metering charges were accrued using energy storage."
def generate_total_bill_comparison_chart(self, *args): """Generates the multiset bar chart comparing total bill with and without energy storage each month.""" n_cats = 2 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) multisetbar_data = OrderedDict() for ix, op in enumerate(self.chart_data, start=0): name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] bar_group = [[ 'without ES', rgba_to_fraction(colors[0]), float(solved_op.total_bill_without_es) ]] bar_group.append([ 'with ES', rgba_to_fraction(colors[1]), float(solved_op.total_bill_with_es) ]) multisetbar_data[label] = bar_group self.chart.draw_chart(multisetbar_data) # generate report text self.title.text = "Here's the total bill with and without energy storage for each month." self.desc.text = 'The total bill is the sum of demand charges, energy charges, and net metering charges or credits. ' report_templates = [] total_bill_difference = sum(op[1].total_bill_with_es - op[1].total_bill_without_es for op in self.chart_data) if total_bill_difference < 0: relation = 'decrease' total_difference_str = "It looks like the ESS was able to [b]{0}[/b] the total charges over the year by [b]{1}[/b].".format( relation, format_dollar_string(abs(total_bill_difference))) report_templates.append(total_difference_str) self.desc.text += ' '.join(report_templates) self.is_drawn = True
def generate_energy_charge_comparison_chart(self, *args): """Generates the multiset bar chart comparing total energy charges with and without energy storage each month.""" if any(op[1].has_energy_charges() for op in self.chart_data): n_cats = 2 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) multisetbar_data = OrderedDict() for ix, op in enumerate(self.chart_data, start=0): name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] results = solved_op.results bar_group = [['without ES', rgba_to_fraction(colors[0]), float(solved_op.energy_charge_without_es)]] bar_group.append(['with ES', rgba_to_fraction(colors[1]), float(solved_op.energy_charge_with_es)]) multisetbar_data[label] = bar_group self.chart.draw_chart(multisetbar_data) self.title.text = "Here are the energy charge totals each month." self.desc.text = 'The energy charge total is based on net energy consumption and different time-of-use rates. The ESS is useful for reducing energy consumption during high time-of-use periods. ' report_templates = [ ] total_energy_charge_difference = sum(op[1].energy_charge_with_es - op[1].energy_charge_without_es for op in self.chart_data) if total_energy_charge_difference < 0: relation = 'decrease' total_difference_str = "It looks like the ESS was able to [b]{0}[/b] the total energy charges over the year by [b]{1}[/b].".format(relation, format_dollar_string(abs(total_energy_charge_difference))) report_templates.append(total_difference_str) else: relation = 'increased' total_difference_str = "It looks like the total energy charges over the year with the ESS [b]{0}[/b] by [b]{1}[/b]. This is likely due to opportunities for decreasing demand charges or obtaining net metering credits.".format(relation, format_dollar_string(abs(total_energy_charge_difference))) report_templates.append(total_difference_str) self.desc.text += ' '.join(report_templates) self.is_drawn = True else: self.title.text = "It looks like there were no energy charges." self.desc.text = "The particular rate structure you selected resulted in no energy charges. Either there are no time-of-use energy charges or no savings on energy charges were accrued using energy storage."
def get_background_color(self, input_text): """Change the background color depending on the text input.""" try: ix = divmod(int(input_text), len(PALETTE))[1] return_color = rgba_to_fraction(PALETTE[ix]) except ValueError: return_color = (1, 1, 1, 1) return return_color
def generate_peak_demand_comparison_chart(self, *args): """Generates the multiset bar chart comparing peak monthly demand with and without energy storage each month.""" n_cats = 2 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) multisetbar_data = OrderedDict() for ix, op in enumerate(self.chart_data, start=0): name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] results = solved_op.results pfpk_with_es = solved_op.model.pfpk.value pfpk_without_es = max(solved_op.model.pnet) bar_group = [[ 'without ES', rgba_to_fraction(colors[0]), int(pfpk_without_es) ]] bar_group.append( ['with ES', rgba_to_fraction(colors[1]), int(pfpk_with_es)]) multisetbar_data[label] = bar_group self.chart.draw_chart(multisetbar_data) self.title.text = "Here are the peak demand values each month." self.desc.text = 'The peak demand value each month is used to compute flat demand charges, if applicable. ' report_templates = [] if all(op[1].model.flt_dr == 0 for op in self.chart_data): report_templates.append( "For this rate structure, there were no flat demand charges.") self.desc.text += ' '.join(report_templates) self.is_drawn = True
def reset_table(self): """Builds the table column headers if necessary and removes all data entries.""" if not self.col_headers.children: for month in calendar.month_abbr[1:]: col_header = BodyTextBase(text=month, color=rgba_to_fraction(PALETTE[1]), font_size=20) self.col_headers.add_widget(col_header) while len(self.data_grid.children) > 0: for widget in self.data_grid.children: self.data_grid.remove_widget(widget)
def generate_total_bill_bar_chart(self, *args): """Generates bar chart showing the total bill with energy storage each month.""" bar_data = [] if len(self.chart_data) > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, len(self.chart_data)) for ix, op in enumerate(self.chart_data, start=0): name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] results = solved_op.results bar_color = colors[divmod(ix, len(colors))[1]] bar_data.append([ label, rgba_to_fraction(bar_color), float(solved_op.total_bill_with_es) ]) self.chart.draw_chart(bar_data) max_bar = self.chart.max_bar min_bar = self.chart.min_bar # generate report text self.title.text = "Here's the total bill for each month." self.desc.text = 'The total bill is the sum of demand charges, energy charges, and net metering charges. ' total_charges_str = format_dollar_string( sum(op[1].total_bill_with_es for op in self.chart_data)) month_high_str = format_dollar_string(max_bar.value) month_low_str = format_dollar_string(min_bar.value) report_templates = [ 'The total charges for the year was [b]{0}[/b].'.format( total_charges_str), 'The highest bill for a month was [b]{0}[/b] in [b]{1}[/b].'. format( month_high_str, calendar.month_name[list( calendar.month_abbr).index(max_bar.name)]), 'The lowest bill for a month was [b]{0}[/b] in [b]{1}[/b].'.format( month_low_str, calendar.month_name[list( calendar.month_abbr).index(min_bar.name)]), ] self.desc.text += ' '.join(report_templates) self.is_drawn = True
def generate_total_bill_stackedbar_chart(self, *args): """TODO: Probably deprecate this since we can't guarantee non-negative quantities.""" stackedbar_data = OrderedDict() charge_sources = [ ('energy charges', 'energy_charge_with_es'), ('demand charges', 'demand_charge_with_es'), ('NEM charges', 'nem_charge_with_es'), ] if sum([x[1].nem_charge_without_es for x in self.chart_data]) + sum( [x[1].nem_charge_with_es for x in self.chart_data]) == 0: n_cats = 2 else: n_cats = 3 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) for op in self.chart_data: name = op[0] month = name.split(' | ')[1] label = month solved_op = op[1] bar_stack = [] for iy, source in enumerate(charge_sources[:n_cats], start=0): component_color = colors[iy] savings = float(getattr(solved_op, source[-1])) bar_stack.append( [source[0], rgba_to_fraction(component_color), savings]) stackedbar_data[label] = bar_stack self.chart.draw_chart(stackedbar_data) self.title.text = "Here's the breakdown of the total bill with energy storage each month." self.desc.text = '' report_templates = [] self.desc.text += ' '.join(report_templates)
def generate_total_savings_donut_chart(self, *args): """TODO: Probably deprecate this since we can't guarantee non-negative quantities.""" donut_data = [] savings_sources = [ ('energy charges', 'energy_charge_with_es', 'energy_charge_without_es'), ('demand charges', 'demand_charge_with_es', 'demand_charge_without_es'), ('NEM charges', 'nem_charge_with_es', 'nem_demand_charge_without_es'), ] total_savings = 0 if sum([x[1].nem_charge_without_es for x in self.chart_data]) + sum( [x[1].nem_charge_with_es for x in self.chart_data]) <= 0: n_cats = 2 else: n_cats = 3 if n_cats > len(PALETTE): colors = PALETTE else: colors = sample(PALETTE, n_cats) for ix, source in enumerate(savings_sources[:n_cats], start=0): savings = sum([ getattr(op[1], source[-1]) - getattr(op[1], source[1]) for op in self.chart_data ]) total_savings += savings donut_data.append( [source[0], rgba_to_fraction(colors[ix]), savings]) # generate chart self.chart.draw_chart(donut_data) # generate report text self.title.text = "Here are the savings from each charge source when using energy storage." self.desc.text = '' report_templates = [ 'The [b]total[/b] savings from energy storage was [b]${0:,.2f}[/b].' .format(total_savings), ] self.desc.text += ' '.join(report_templates)
def generate_schedule_charts(self, *args): """Draws the weekday and weekend rate schedule charts.""" weekday_schedule_data = self.rate_structure.get( 'energyweekdayschedule', []) weekend_schedule_data = self.rate_structure.get( 'energyweekendschedule', []) if weekday_schedule_data and weekend_schedule_data: n_tiers = len(np.unique(weekday_schedule_data)) # Select chart colors. palette = [rgba_to_fraction(color) for color in PALETTE][:n_tiers] labels = calendar.month_abbr[1:] # Draw charts. self.weekday_chart.draw_chart(np.array(weekday_schedule_data), palette, labels) self.weekend_chart.draw_chart(np.array(weekend_schedule_data), palette, labels)