def process_site( sess, site, month_start, month_finish, forecast_date, tmp_file): site_code = site.code associates = [] sources = set() generator_types = set() metering_type = 'no-supply' problem = '' month_data = {} for stream_name in [ 'import-net', 'export-net', 'import-gen', 'export-gen', 'import-3rd-party', 'export-3rd-party', 'msp', 'used', 'used-3rd-party']: month_data[stream_name + '-kwh'] = 0 month_data[stream_name + '-gbp'] = 0 billed_gbp = 0 billed_kwh = 0 for group in site.groups(sess, month_start, month_finish, False): for cand_site in group.sites: cand_site_code = cand_site.code if cand_site_code != site_code and \ cand_site_code not in associates: associates.append(cand_site_code) for cand_supply in group.supplies: sources.add(cand_supply.source.code) if cand_supply.generator_type is not None: generator_types.add(cand_supply.generator_type.code) for cand_era in cand_supply.find_eras( sess, group.start_date, group.finish_date): if metering_type != 'hh': if cand_era.pc.code == '00': metering_type = 'hh' elif metering_type != 'amr': if len(cand_era.channels) > 0: metering_type = 'amr' elif metering_type != 'nhh': if cand_era.mtc.meter_type.code not in [ 'UM', 'PH']: metering_type = 'nhh' else: metering_type = 'unmetered' for group in site.groups(sess, month_start, month_finish, True): if group.start_date > start_date: chunk_start = group.start_date else: chunk_start = start_date if group.finish_date > finish_date: chunk_finish = finish_date else: chunk_finish = group.finish_date for supply in group.supplies: source_code = supply.source.code for era in sess.query(Era).filter( Era.supply == supply, Era.start_date <= chunk_finish, or_( Era.finish_date == null(), Era.finish_date >= chunk_start)): tmp_file.write(' ') # GBP if era.start_date > chunk_start: bill_start = era.start_date else: bill_start = chunk_start if hh_after(era.finish_date, chunk_finish): bill_finish = chunk_finish else: bill_finish = era.finish_date supply_source = None supplier_contract = era.imp_supplier_contract if supplier_contract is not None: supply_source = computer.SupplySource( sess, bill_start, bill_finish, forecast_date, era, True, tmp_file, caches) if supply_source.measurement_type not in ['hh', 'amr']: kwh = sum( hh['msp-kwh'] for hh in supply_source.hh_data) if source_code in ('net', 'gen-net'): month_data['import-net-kwh'] += kwh elif source_code in ('3rd-party', '3rd-party-reverse'): month_data['import-3rd-party-kwh'] += kwh import_vb_function = computer.contract_func( caches, supplier_contract, 'virtual_bill', tmp_file) if import_vb_function is None: problem += "Can't find the virtual_bill function in " \ "the supplier contract. " else: import_vb_function(supply_source) v_bill = supply_source.supplier_bill if 'problem' in v_bill and len(v_bill['problem']) > 0: problem += 'Supplier Problem: ' + v_bill['problem'] try: gbp = v_bill['net-gbp'] except KeyError: problem += 'For the supply ' + \ supply_source.mpan_core + \ ' the virtual bill ' + str(v_bill) + \ ' from the contract ' + \ supplier_contract.getName() + \ ' does not contain the net-gbp key.' if source_code in ('net', 'gen-net'): month_data['import-net-gbp'] += gbp elif source_code in ('3rd-party', '3rd-party-reverse'): month_data['import-3rd-party-gbp'] += gbp if supply_source is None: supply_source = computer.SupplySource( sess, bill_start, bill_finish, forecast_date, era, False, tmp_file, caches) dc_contract = era.hhdc_contract supply_source.contract_func( dc_contract, 'virtual_bill')(supply_source) dc_bill = supply_source.dc_bill dc_gbp = dc_bill['net-gbp'] if 'problem' in dc_bill and len(dc_bill['problem']) > 0: problem += 'DC Problem: ' + dc_bill['problem'] mop_contract = era.mop_contract mop_bill_function = supply_source.contract_func( mop_contract, 'virtual_bill') mop_bill_function(supply_source) mop_bill = supply_source.mop_bill mop_gbp = mop_bill['net-gbp'] if 'problem' in mop_bill and len(mop_bill['problem']) > 0: problem += 'MOP Problem: ' + mop_bill['problem'] if source_code in ('3rd-party', '3rd-party-reverse'): month_data['import-3rd-party-gbp'] += dc_gbp + mop_gbp else: month_data['import-net-gbp'] += dc_gbp + mop_gbp for bill in sess.query(Bill).filter( Bill.supply == supply, Bill.start_date <= chunk_finish, Bill.finish_date >= chunk_start): bill_start = bill.start_date bill_finish = bill.finish_date bill_duration = totalseconds(bill_finish - bill_start) + \ (30 * 60) overlap_duration = totalseconds( min(bill_finish, chunk_finish) - max(bill_start, chunk_start)) + (30 * 60) overlap_proportion = float(overlap_duration) / bill_duration billed_gbp += overlap_proportion * float(bill.net) billed_kwh += overlap_proportion * float(bill.kwh) displaced_era = computer.displaced_era( sess, group, chunk_start, chunk_finish) site_ds = computer.SiteSource( sess, site, chunk_start, chunk_finish, forecast_date, tmp_file, caches, displaced_era) if displaced_era is not None: computer.contract_func( caches, displaced_era.imp_supplier_contract, 'displaced_virtual_bill', tmp_file)(site_ds) month_data['msp-gbp'] += site_ds.supplier_bill['net-gbp'] for stream_name in ( 'import-3rd-party', 'export-3rd-party', 'import-net', 'export-net', 'import-gen', 'export-gen', 'msp'): name = stream_name + '-kwh' month_data[name] += sum(hh[name] for hh in site_ds.hh_data) month_data['used-3rd-party-kwh'] = \ month_data['import-3rd-party-kwh'] - \ month_data['export-3rd-party-kwh'] month_data['used-3rd-party-gbp'] = month_data['import-3rd-party-gbp'] month_data['used-gbp'] += \ month_data['import-net-gbp'] + month_data['msp-gbp'] + \ month_data['used-3rd-party-gbp'] month_data['used-kwh'] += month_data['msp-kwh'] + \ month_data['used-3rd-party-kwh'] + month_data['import-net-kwh'] result = [ site.code, site.name, ','.join(associates), ','.join(sorted(list(sources))), '.'.join(sorted(list(generator_types))), hh_format(month_finish), month_data['import-net-kwh'], month_data['msp-kwh'], month_data['export-net-kwh'], month_data['used-kwh'], month_data['export-gen-kwh'], month_data['import-gen-kwh'], month_data['import-3rd-party-kwh'], month_data['export-3rd-party-kwh'], month_data['import-net-gbp'], month_data['msp-gbp'], 0, month_data['used-gbp'], month_data['used-3rd-party-gbp'], billed_kwh, billed_gbp, metering_type, problem] return result
def content(): global scenario_props sess = None try: sess = db.session() if scenario_props is None: scenario_contract = Contract.get_supplier_by_id(sess, scenario_id) scenario_props = scenario_contract.make_properties() base_name.append(scenario_contract.name) for contract in sess.query(Contract).join(MarketRole).filter( MarketRole.code == 'Z'): try: props = scenario_props[contract.name] except KeyError: continue try: rate_start = props['start_date'] except KeyError: raise UserException( "In " + scenario_contract.name + " for the rate " + contract.name + " the start_date is missing.") if rate_start is not None: rate_start = rate_start.replace(tzinfo=pytz.utc) lib = globals()[contract.name] if hasattr(lib, 'create_future_func'): future_funcs[contract.id] = { 'start_date': rate_start, 'func': lib.create_future_func( props['multiplier'], props['constant'])} start_date = scenario_props['scenario_start'] if start_date is None: start_date = datetime.datetime( now.year, now.month, 1, tzinfo=pytz.utc) else: start_date = start_date.replace(tzinfo=pytz.utc) base_name.append( hh_format(start_date).replace(' ', '_').replace(':', ''). replace('-', '')) months = scenario_props['scenario_duration'] base_name.append('for') base_name.append(str(months)) base_name.append('months') finish_date = start_date + relativedelta(months=months) if 'kwh_start' in scenario_props: kwh_start = scenario_props['kwh_start'] else: kwh_start = None if kwh_start is None: kwh_start = computer.forecast_date() else: kwh_start = kwh_start.replace(tzinfo=pytz.utc) sites = sess.query(Site).join(SiteEra).join(Era).filter( Era.start_date <= finish_date, or_( Era.finish_date == null(), Era.finish_date >= start_date)).distinct() if site_id is not None: site = Site.get_by_id(sess, site_id) sites = sites.filter(Site.id == site.id) base_name.append('site') base_name.append(site.code) if supply_id is not None: supply = Supply.get_by_id(sess, supply_id) base_name.append('supply') base_name.append(str(supply.id)) sites = sites.filter(Era.supply == supply) running_name, finished_name = dloads.make_names( '_'.join(base_name) + '.ods', user) rf = open(running_name, "wb") f = odswriter.writer(rf, '1.1') group_tab = f.new_sheet("Site Level") sup_tab = f.new_sheet("Supply Level") changes = defaultdict(list, {}) try: kw_changes = scenario_props['kw_changes'] except KeyError: kw_changes = '' for row in csv.reader(StringIO.StringIO(kw_changes)): if len(''.join(row).strip()) == 0: continue if len(row) != 4: raise UserException( "Can't interpret the row " + str(row) + " it should be of " "the form SITE_CODE, USED / GENERATED, DATE, MULTIPLIER") site_code, typ, date_str, kw_str = row date = datetime.datetime.strptime( date_str.strip(), "%Y-%m-%d").replace(tzinfo=pytz.utc) changes[site_code.strip()].append( { 'type': typ.strip(), 'date': date, 'multiplier': float(kw_str)}) sup_header_titles = [ 'imp-mpan-core', 'exp-mpan-core', 'metering-type', 'source', 'generator-type', 'supply-name', 'msn', 'pc', 'site-id', 'site-name', 'associated-site-ids', 'month'] site_header_titles = [ 'site-id', 'site-name', 'associated-site-ids', 'month', 'metering-type', 'sources', 'generator-types'] summary_titles = [ 'import-net-kwh', 'export-net-kwh', 'import-gen-kwh', 'export-gen-kwh', 'import-3rd-party-kwh', 'export-3rd-party-kwh', 'displaced-kwh', 'used-kwh', 'used-3rd-party-kwh', 'import-net-gbp', 'export-net-gbp', 'import-gen-gbp', 'export-gen-gbp', 'import-3rd-party-gbp', 'export-3rd-party-gbp', 'displaced-gbp', 'used-gbp', 'used-3rd-party-gbp', 'billed-import-net-kwh', 'billed-import-net-gbp'] title_dict = {} for cont_type, con_attr in ( ('mop', Era.mop_contract), ('dc', Era.hhdc_contract), ('imp-supplier', Era.imp_supplier_contract), ('exp-supplier', Era.exp_supplier_contract)): titles = [] title_dict[cont_type] = titles conts = sess.query(Contract).join(con_attr) \ .join(Era.supply).join(Source).filter( Era.start_date <= start_date, or_( Era.finish_date == null(), Era.finish_date >= start_date), Source.code.in_(('net', '3rd-party')) ).distinct().order_by(Contract.id) if supply_id is not None: conts = conts.filter(Era.supply_id == supply_id) for cont in conts: title_func = computer.contract_func( report_context, cont, 'virtual_bill_titles', None) if title_func is None: raise Exception( "For the contract " + cont.name + " there doesn't seem to be a " "'virtual_bill_titles' function.") for title in title_func(): if title not in titles: titles.append(title) sup_tab.writerow( sup_header_titles + summary_titles + [None] + ['mop-' + t for t in title_dict['mop']] + [None] + ['dc-' + t for t in title_dict['dc']] + [None] + ['imp-supplier-' + t for t in title_dict['imp-supplier']] + [None] + ['exp-supplier-' + t for t in title_dict['exp-supplier']]) group_tab.writerow(site_header_titles + summary_titles) sites = sites.all() month_start = start_date while month_start < finish_date: month_finish = month_start + relativedelta(months=1) - HH for site in sites: site_changes = changes[site.code] site_associates = set() site_category = None site_sources = set() site_gen_types = set() site_month_data = defaultdict(int) for group in site.groups( sess, month_start, month_finish, False): site_associates.update( set( s.code for s in group.sites if s.code != site.code)) for cand_supply in group.supplies: site_sources.add(cand_supply.source.code) if cand_supply.generator_type is not None: site_gen_types.add(cand_supply.generator_type.code) for cand_era in cand_supply.find_eras( sess, group.start_date, group.finish_date): if site_category != 'hh': if cand_era.pc.code == '00': site_category = 'hh' elif site_category != 'amr': if len(cand_era.channels) > 0: site_category = 'amr' elif site_category != 'nhh': if cand_era.mtc.meter_type.code \ not in ['UM', 'PH']: site_category = 'nhh' else: site_category = 'unmetered' for group in site.groups( sess, month_start, month_finish, True): calcs = [] deltas = defaultdict(int) group_associates = set( s.code for s in group.sites if s.code != site.code) for supply in group.supplies: if supply_id is not None and supply.id != supply_id: continue for era in sess.query(Era).join(Supply) \ .join(Source).filter( Era.supply == supply, Era.start_date <= group.finish_date, or_( Era.finish_date == null(), Era.finish_date >= group.start_date)): if era.start_date > group.start_date: ss_start = era.start_date else: ss_start = group.start_date if hh_before(era.finish_date, group.finish_date): ss_finish = era.finish_date else: ss_finish = group.finish_date if era.imp_mpan_core is None: imp_ss = None else: imp_ss = SupplySource( sess, ss_start, ss_finish, kwh_start, era, True, None, report_context) if era.exp_mpan_core is None: exp_ss = None measurement_type = imp_ss.measurement_type else: exp_ss = SupplySource( sess, ss_start, ss_finish, kwh_start, era, False, None, report_context) measurement_type = exp_ss.measurement_type order = meter_order[measurement_type] calcs.append( ( order, era.imp_mpan_core, era.exp_mpan_core, imp_ss, exp_ss)) if imp_ss is not None and len(era.channels) == 0: for hh in imp_ss.hh_data: deltas[hh['start-date']] += hh['msp-kwh'] imp_net_delts = defaultdict(int) exp_net_delts = defaultdict(int) imp_gen_delts = defaultdict(int) displaced_era = computer.displaced_era( sess, group, group.start_date, group.finish_date) site_ds = computer.SiteSource( sess, site, group.start_date, group.finish_date, kwh_start, None, report_context, displaced_era) for hh in site_ds.hh_data: try: delta = deltas[hh['start-date']] hh['import-net-kwh'] += delta hh['used-kwh'] += delta except KeyError: pass for hh in site_ds.hh_data: for change in site_changes: if change['type'] == 'used' and \ change['date'] <= hh['start-date']: used = change['multiplier'] * hh['used-kwh'] exp_net = max( 0, hh['import-gen-kwh'] - hh['export-gen-kwh'] - used) exp_net_delt = exp_net - hh['export-net-kwh'] exp_net_delts[hh['start-date']] += exp_net_delt displaced = hh['import-gen-kwh'] - \ hh['export-gen-kwh'] - exp_net imp_net = used - displaced imp_delt = imp_net - hh['import-net-kwh'] imp_net_delts[hh['start-date']] += imp_delt hh['import-net-kwh'] = imp_net hh['used-kwh'] = used hh['export-net-kwh'] = exp_net hh['msp-kwh'] = displaced elif change['type'] == 'generated' and \ change['date'] <= hh['start-date']: imp_gen = change['multiplier'] * \ hh['import-gen-kwh'] imp_gen_delt = imp_gen - hh['import-gen-kwh'] exp_net = max( 0, imp_gen - hh['export-gen-kwh'] - hh['used-kwh']) exp_net_delt = exp_net - hh['export-net-kwh'] exp_net_delts[hh['start-date']] += exp_net_delt displaced = imp_gen - hh['export-gen-kwh'] - \ exp_net imp_net = hh['used-kwh'] - displaced imp_net_delt = imp_net - hh['import-net-kwh'] imp_net_delts[hh['start-date']] += imp_net_delt imp_gen_delts[hh['start-date']] += imp_gen_delt hh['import-net-kwh'] = imp_net hh['export-net-kwh'] = exp_net hh['import-gen-kwh'] = imp_gen hh['msp-kwh'] = displaced if displaced_era is not None and supply_id is None: month_data = {} for sname in ( 'import-net', 'export-net', 'import-gen', 'export-gen', 'import-3rd-party', 'export-3rd-party', 'msp', 'used', 'used-3rd-party', 'billed-import-net'): for xname in ('kwh', 'gbp'): month_data[sname + '-' + xname] = 0 month_data['used-kwh'] = \ month_data['displaced-kwh'] = \ sum(hh['msp-kwh'] for hh in site_ds.hh_data) disp_supplier_contract = \ displaced_era.imp_supplier_contract disp_vb_function = computer.contract_func( report_context, disp_supplier_contract, 'displaced_virtual_bill', None) if disp_vb_function is None: raise UserException( "The supplier contract " + disp_supplier_contract.name + " doesn't have the displaced_virtual_bill() " "function.") disp_vb_function(site_ds) disp_supplier_bill = site_ds.supplier_bill try: gbp = disp_supplier_bill['net-gbp'] except KeyError: disp_supplier_bill['problem'] += \ 'For the supply ' + \ site_ds.mpan_core + \ ' the virtual bill ' + \ str(disp_supplier_bill) + \ ' from the contract ' + \ disp_supplier_contract.name + \ ' does not contain the net-gbp key.' month_data['used-gbp'] = \ month_data['displaced-gbp'] = \ site_ds.supplier_bill['net-gbp'] out = [ None, None, displaced_era.make_meter_category(), 'displaced', None, None, None, None, site.code, site.name, ','.join(sorted(list(group_associates))), month_finish] + \ [month_data[t] for t in summary_titles] sup_tab.writerow(out) for k, v in month_data.iteritems(): site_month_data[k] += v for i, ( order, imp_mpan_core, exp_mpan_core, imp_ss, exp_ss) in enumerate(sorted(calcs)): if imp_ss is None: era = exp_ss.era else: era = imp_ss.era supply = era.supply source = supply.source source_code = source.code site_sources.add(source_code) month_data = {} for name in ( 'import-net', 'export-net', 'import-gen', 'export-gen', 'import-3rd-party', 'export-3rd-party', 'displaced', 'used', 'used-3rd-party', 'billed-import-net'): for sname in ('kwh', 'gbp'): month_data[name + '-' + sname] = 0 if source_code == 'net': delts = imp_net_delts elif source_code == 'gen': delts = imp_gen_delts else: delts = [] if len(delts) > 0 and imp_ss is not None: for hh in imp_ss.hh_data: diff = hh['msp-kwh'] + delts[hh['start-date']] if diff < 0: hh['msp-kwh'] = 0 hh['msp-kw'] = 0 delts[hh['start-date']] -= hh['msp-kwh'] else: hh['msp-kwh'] += delts[hh['start-date']] hh['msp-kw'] += hh['msp-kwh'] / 2 del delts[hh['start-date']] left_kwh = sum(delts.values()) if left_kwh > 0: first_hh = imp_ss.hh_data[0] first_hh['msp-kwh'] += left_kwh first_hh['msp-kw'] += left_kwh / 2 imp_supplier_contract = era.imp_supplier_contract if imp_supplier_contract is not None: import_vb_function = computer.contract_func( report_context, imp_supplier_contract, 'virtual_bill', None) if import_vb_function is None: raise UserException( "The supplier contract " + imp_supplier_contract.name + " doesn't have the virtual_bill() " "function.") import_vb_function(imp_ss) imp_supplier_bill = imp_ss.supplier_bill try: gbp = imp_supplier_bill['net-gbp'] except KeyError: imp_supplier_bill['problem'] += \ 'For the supply ' + \ imp_ss.mpan_core + \ ' the virtual bill ' + \ str(imp_supplier_bill) + \ ' from the contract ' + \ imp_supplier_contract.name + \ ' does not contain the net-gbp key.' if source_code in ('net', 'gen-net'): month_data['import-net-gbp'] += gbp month_data['used-gbp'] += gbp elif source_code == '3rd-party': month_data['import-3rd-party-gbp'] += gbp month_data['used-gbp'] += gbp elif source_code == '3rd-party-reverse': month_data['export-3rd-party-gbp'] += gbp month_data['used-gbp'] -= gbp kwh = sum( hh['msp-kwh'] for hh in imp_ss.hh_data) if source_code in ('net', 'gen-net'): month_data['import-net-kwh'] += kwh month_data['used-kwh'] += kwh elif source_code == '3rd-party': month_data['import-3rd-party-kwh'] += kwh month_data['used-kwh'] += kwh elif source_code == '3rd-party-reverse': month_data['export-3rd-party-kwh'] += kwh month_data['used-kwh'] -= kwh elif source_code in ('gen', 'gen-net'): month_data['import-gen-kwh'] += kwh exp_supplier_contract = era.exp_supplier_contract if exp_supplier_contract is None: kwh = sess.query( func.coalesce( func.sum( cast(HhDatum.value, Float)), 0)). \ join(Channel).filter( Channel.era == era, Channel.channel_type == 'ACTIVE', Channel.imp_related == false()).scalar() if source_code == 'gen': month_data['export-net-kwh'] += kwh else: export_vb_function = computer.contract_func( report_context, exp_supplier_contract, 'virtual_bill', None) export_vb_function(exp_ss) exp_supplier_bill = exp_ss.supplier_bill try: gbp = exp_supplier_bill['net-gbp'] except KeyError: exp_supplier_bill['problem'] += \ 'For the supply ' + \ imp_ss.mpan_core + \ ' the virtual bill ' + \ str(imp_supplier_bill) + \ ' from the contract ' + \ imp_supplier_contract.name + \ ' does not contain the net-gbp key.' kwh = sum(hh['msp-kwh'] for hh in exp_ss.hh_data) if source_code in ('net', 'gen-net'): month_data['export-net-kwh'] += kwh month_data['export-net-gbp'] += gbp elif source_code in \ ('3rd-party', '3rd-party-reverse'): month_data['export-3rd-party-kwh'] += kwh month_data['export-3rd-party-gbp'] += gbp month_data['used-kwh'] -= kwh month_data['used-gbp'] -= gbp elif source_code == 'gen': month_data['export-gen-kwh'] += kwh sss = exp_ss if imp_ss is None else imp_ss dc_contract = era.hhdc_contract sss.contract_func( dc_contract, 'virtual_bill')(sss) dc_bill = sss.dc_bill gbp = dc_bill['net-gbp'] mop_contract = era.mop_contract mop_bill_function = sss.contract_func( mop_contract, 'virtual_bill') mop_bill_function(sss) mop_bill = sss.mop_bill gbp += mop_bill['net-gbp'] if source_code in ('3rd-party', '3rd-party-reverse'): month_data['import-3rd-party-gbp'] += gbp else: month_data['import-net-gbp'] += gbp month_data['used-gbp'] += gbp if source_code in ('gen', 'gen-net'): generator_type = supply.generator_type.code site_gen_types.add(generator_type) else: generator_type = None sup_category = era.make_meter_category() if CATEGORY_ORDER[site_category] < \ CATEGORY_ORDER[sup_category]: site_category = sup_category for bill in sess.query(Bill).filter( Bill.supply == supply, Bill.start_date <= sss.finish_date, Bill.finish_date >= sss.start_date): bill_start = bill.start_date bill_finish = bill.finish_date bill_duration = totalseconds( bill_finish - bill_start) + (30 * 60) overlap_duration = totalseconds( min(bill_finish, sss.finish_date) - max(bill_start, sss.start_date)) + (30 * 60) overlap_proportion = \ float(overlap_duration) / bill_duration month_data['billed-import-net-kwh'] += \ overlap_proportion * float(bill.kwh) month_data['billed-import-net-gbp'] += \ overlap_proportion * float(bill.net) out = [ era.imp_mpan_core, era.exp_mpan_core, sup_category, source_code, generator_type, supply.name, era.msn, era.pc.code, site.code, site.name, ','.join(sorted(list(site_associates))), month_finish] + [ month_data[t] for t in summary_titles] + [None] + [ (mop_bill[t] if t in mop_bill else None) for t in title_dict['mop']] + [None] + \ [(dc_bill[t] if t in dc_bill else None) for t in title_dict['dc']] if imp_supplier_contract is None: out += [None] * \ (len(title_dict['imp-supplier']) + 1) else: out += [None] + [ ( imp_supplier_bill[t] if t in imp_supplier_bill else None) for t in title_dict['imp-supplier']] if exp_supplier_contract is not None: out += [None] + [ ( exp_supplier_bill[t] if t in exp_supplier_bill else None) for t in title_dict['exp-supplier']] for k, v in month_data.iteritems(): site_month_data[k] += v sup_tab.writerow(out) sess.rollback() group_tab.writerow( [ site.code, site.name, ''.join(sorted(list(site_associates))), month_finish, site_category, ', '.join(sorted(list(site_sources))), ', '.join(sorted(list(site_gen_types)))] + [site_month_data[k] for k in summary_titles]) month_start += relativedelta(months=1) except: msg = traceback.format_exc() sys.stderr.write(msg + '\n') group_tab.writerow(["Problem " + msg]) finally: try: f.close() rf.close() os.rename(running_name, finished_name) if sess is not None: sess.close() except: msg = traceback.format_exc() r_name, f_name = dloads.make_names('error.txt', user) ef = open(r_name, "wb") ef.write(msg + '\n') ef.close()
def content(): sess = None try: sess = db.session() yield ','.join( ( 'Site Code', 'Site Name', 'Associated Site Ids', 'From', 'To', 'Gen Types', 'CHP kWh', 'LM kWh', 'Turbine kWh', 'PV kWh')) finish_date = datetime.datetime( end_year, end_month, 1, tzinfo=pytz.utc) + \ relativedelta(months=1) - HH start_date = datetime.datetime( end_year, end_month, 1, tzinfo=pytz.utc) - \ relativedelta(months=months-1) forecast_date = computer.forecast_date() contract = Contract.get_supplier_by_id(sess, contract_id) sites = sess.query(Site).join(SiteEra).join(Era).join(Supply). \ join(Source).filter( or_(Era.finish_date == null(), Era.finish_date >= start_date), Era.start_date <= finish_date, or_( Source.code.in_(('gen', 'gen-net')), Era.exp_mpan_core != null())).distinct() bill_titles = computer.contract_func( caches, contract, 'displaced_virtual_bill_titles', None)() for title in bill_titles: if title == 'total-msp-kwh': title = 'total-displaced-msp-kwh' yield ',' + title yield '\n' for site in sites: month_start = start_date month_finish = month_start + relativedelta(months=1) - HH while not month_finish > finish_date: for site_group in site.groups( sess, month_start, month_finish, True): if site_group.start_date > month_start: chunk_start = site_group.start_date else: chunk_start = month_start if site_group.finish_date > month_finish: chunk_finish = month_finish else: chunk_finish = site_group.finish_date displaced_era = computer.displaced_era( sess, site_group, chunk_start, chunk_finish) if displaced_era is None: continue supplier_contract = displaced_era.imp_supplier_contract if contract is not None and contract != supplier_contract: continue linked_sites = ','.join( a_site.code for a_site in site_group.sites if not a_site == site) generator_types = ' '.join( sorted( [ supply.generator_type.code for supply in site_group.supplies if supply.generator_type is not None])) yield ','.join( '"' + value + '"' for value in [ site.code, site.name, linked_sites, hh_format(chunk_start), hh_format(chunk_finish), generator_types]) total_gen_breakdown = {} results = iter( sess.execute( "select supply.id, hh_datum.value, " "hh_datum.start_date, channel.imp_related, " "source.code, generator_type.code as " "gen_type_code from hh_datum, channel, source, " "era, supply left outer join generator_type on " "supply.generator_type_id = generator_type.id " "where hh_datum.channel_id = channel.id and " "channel.era_id = era.id and era.supply_id = " "supply.id and supply.source_id = source.id and " "channel.channel_type = 'ACTIVE' and not " "(source.code = 'net' and channel.imp_related " "is true) and hh_datum.start_date >= " ":chunk_start and hh_datum.start_date " "<= :chunk_finish and " "supply.id = any(:supply_ids) order " "by hh_datum.start_date, supply.id", params={ 'chunk_start': chunk_start, 'chunk_finish': chunk_finish, 'supply_ids': [ s.id for s in site_group.supplies]})) try: res = results.next() hhChannelValue = res.value hhChannelStartDate = res.start_date imp_related = res.imp_related source_code = res.code gen_type = res.gen_type_code hh_date = chunk_start while hh_date <= finish_date: gen_breakdown = {} exported = 0 while hhChannelStartDate == hh_date: if not imp_related and source_code in ( 'net', 'gen-net'): exported += hhChannelValue if (imp_related and source_code == 'gen') or \ (not imp_related and source_code == 'gen-net'): gen_breakdown[gen_type] = \ gen_breakdown.setdefault( gen_type, 0) + hhChannelValue if ( not imp_related and source_code == 'gen') or ( imp_related and source_code == 'gen-net'): gen_breakdown[gen_type] = \ gen_breakdown.setdefault( gen_type, 0) - hhChannelValue try: res = results.next() source_code = res.code hhChannelValue = res.value hhChannelStartDate = res.start_date imp_related = res.imp_related gen_type = res.gen_type_code except StopIteration: hhChannelStartDate = None displaced = sum(gen_breakdown.itervalues()) - \ exported added_so_far = 0 for key in sorted(gen_breakdown.iterkeys()): kwh = gen_breakdown[key] if kwh + added_so_far > displaced: total_gen_breakdown[key] = \ total_gen_breakdown.get(key, 0) + \ displaced - added_so_far break else: total_gen_breakdown[key] = \ total_gen_breakdown.get(key, 0) + kwh added_so_far += kwh hh_date += HH except StopIteration: pass for title in ['chp', 'lm', 'turb', 'pv']: yield ',' + str(total_gen_breakdown.get(title, '')) site_ds = computer.SiteSource( sess, site, chunk_start, chunk_finish, forecast_date, None, caches, displaced_era) disp_func = computer.contract_func( caches, supplier_contract, 'displaced_virtual_bill', None) disp_func(site_ds) bill = site_ds.supplier_bill for title in bill_titles: if title in bill: val = bill[title] if isinstance(val, datetime.datetime): val = hh_format(val) else: val = str(val) yield ',"' + val + '"' del bill[title] else: yield ',""' keys = bill.keys() keys.sort() for k in keys: yield ',"' + k + '","' + str(bill[k]) + '"' yield '\n' month_start += relativedelta(months=1) month_finish = month_start + relativedelta(months=1) - HH except: yield traceback.format_exc() finally: if sess is not None: sess.close()
def content(): sess = None try: sess = db.session() march_finish = datetime.datetime(year, 4, 1, tzinfo=pytz.utc) - HH march_start = datetime.datetime(year, 3, 1, tzinfo=pytz.utc) yield ", ".join( ( "Site Code", "Site Name", "Displaced TRIAD 1 Date", "Displaced TRIAD 1 MSP kW", "Displaced TRIAD LAF", "Displaced TRIAD 1 GSP kW", "Displaced TRIAD 2 Date", "Displaced TRIAD 2 MSP kW", "Displaced TRIAD 2 LAF", "Displaced TRIAD 2 GSP kW", "Displaced TRIAD 3 Date", "Displaced TRIAD 3 MSP kW", "Displaced TRIAD 3 LAF", "Displaced TRIAD 3 GSP kW", "Displaced GSP kW", "Displaced Rate GBP / kW", "GBP", ) ) + "\n" forecast_date = computer.forecast_date() if site_id is None: sites = ( sess.query(Site) .join(SiteEra) .join(Era) .join(Supply) .join(Source) .filter( Source.code.in_(("gen", "gen-net")), Era.start_date <= march_finish, or_(Era.finish_date == null(), Era.finish_date >= march_start), ) .distinct() ) else: site = Site.get_by_id(sess, site_id) sites = sess.query(Site).filter(Site.id == site.id) for site in sites: for site_group in site.groups(sess, march_start, march_finish, True): if site_group.start_date > march_start: chunk_start = site_group.start_date else: chunk_start = march_start if not site_group.finish_date < march_finish: chunk_finish = march_finish else: continue yield '"' + site.code + '","' + site.name + '"' displaced_era = computer.displaced_era(sess, site_group, chunk_start, chunk_finish) if displaced_era is None: continue site_ds = computer.SiteSource( sess, site, chunk_start, chunk_finish, forecast_date, None, caches, displaced_era ) duos.duos_vb(site_ds) triad.triad_bill(site_ds) bill = site_ds.supplier_bill values = [] for i in range(1, 4): triad_prefix = "triad-actual-" + str(i) for suffix in ["-date", "-msp-kw", "-laf", "-gsp-kw"]: values.append(bill[triad_prefix + suffix]) values += [bill["triad-actual-" + suf] for suf in ["gsp-kw", "rate", "gbp"]] for value in values: if isinstance(value, datetime.datetime): yield "," + hh_format(value) else: yield "," + str(value) yield "\n" except: yield traceback.format_exc() finally: if sess is not None: sess.close()