def vb(ds): for hh in ds.hh_data: rate = float( get_file_rates(ds.caches, "g_ccl", hh["start_date"])["ccl_gbp_per_kwh"] ) hh["ccl"] = rate
def vb(ds): for hh in ds.hh_data: rate = float( get_file_rates(ds.caches, 'g_ccl', hh['start_date'])['ccl_gbp_per_kwh']) hh['ccl'] = rate
def hh(supply_source): bill = supply_source.supplier_bill rate_set = supply_source.supplier_rate_sets['ro-rate'] try: supply_source.caches['ro'] except KeyError: supply_source.caches['ro'] = {} try: future_funcs = supply_source.caches['future_funcs'] except KeyError: future_funcs = {} supply_source.caches['future_funcs'] = future_funcs try: future_funcs['ro'] except KeyError: future_funcs['ro'] = { 'start_date': None, 'func': create_future_func(1, 0) } for hh in supply_source.hh_data: rate = float( get_file_rates(supply_source.caches, 'ro', hh['start-date'])['ro_gbp_per_msp_kwh']) rate_set.add(rate) bill['ro-msp-kwh'] += hh['msp-kwh'] bill['ro-gbp'] += hh['msp-kwh'] * rate
def ccl(data_source): cache = data_source.caches for hh in data_source.hh_data: rates = get_file_rates(cache, "ccl", hh["start-date"]) rate = float(rates["ccl_gbp_per_msp_kwh"]) hh["ccl-kwh"] = hh["msp-kwh"] hh["ccl-rate"] = rate hh["ccl-gbp"] = hh["msp-kwh"] * rate
def hh(supply_source): bill = supply_source.supplier_bill rate_set = supply_source.supplier_rate_sets['aahedc-rate'] for hh in supply_source.hh_data: bill['aahedc-gsp-kwh'] += hh['gsp-kwh'] rate = float( get_file_rates(supply_source.caches, 'aahedc', hh['start-date'])['aahedc_gbp_per_gsp_kwh']) rate_set.add(rate) bill['aahedc-gbp'] += hh['gsp-kwh'] * rate
def ccl(data_source): rate_set = data_source.supplier_rate_sets['ccl-rate'] cache = data_source.caches for hh in data_source.hh_data: rates = get_file_rates(cache, 'ccl', hh['start-date']) rate = float(rates['ccl_gbp_per_msp_kwh']) rate_set.add(rate) hh['ccl-kwh'] = hh['msp-kwh'] hh['ccl-rate'] = rate hh['ccl-gbp'] = hh['msp-kwh'] * rate
def hh(supply_source): try: supply_source.caches["ro"] except KeyError: supply_source.caches["ro"] = {} for hh in supply_source.hh_data: rate = float( get_file_rates(supply_source.caches, "ro", hh["start-date"])["ro_gbp_per_msp_kwh"]) hh["ro-rate"] = rate hh["ro-msp-kwh"] = hh["msp-kwh"] hh["ro-gbp"] = hh["msp-kwh"] * rate
def file_rate(self, contract_name, timestamp, rate_name): return get_file_rates(self.caches, contract_name, timestamp)[rate_name]
def datum_beginning_22(ds, hh): rs = get_file_rates(ds.caches, ds.dno_code, hh["start-date"]) try: tariff = rs["tariffs"][ds.llfc_code] lafs = rs["lafs"][VL_LOOKUP[ds.voltage_level_code][ds.is_substation]] except KeyError as e: raise BadRequest(str(e)) if ds.is_import: try: day_rate = float(tariff["day-gbp-per-kwh"]) except KeyError as e: raise BadRequest(str(e)) night_rate = float(tariff["night-gbp-per-kwh"]) if 6 < hh["ct-decimal-hour"] <= 23: hh["duos-day-kwh"] = hh["msp-kwh"] hh["duos-day-gbp"] = hh["msp-kwh"] * day_rate else: hh["duos-night-kwh"] = hh["msp-kwh"] hh["duos-night-gbp"] = hh["msp-kwh"] * night_rate if 23 < hh["ct-decimal-hour"] <= 6: slot_name = "night" elif hh["ct-day-of-week"] < 5 and (hh["ct-month"] > 10 or hh["ct-month"] < 3): if 15.5 < hh["ct-decimal-hour"] < 18: slot_name = "winter-weekday-peak" elif 6 < hh["ct-decimal-hour"] < 15: slot_name = "winter-weekday-day" else: slot_name = "other" else: slot_name = "other" try: hh["laf"] = float(lafs[slot_name]) except KeyError as e: raise BadRequest(str(e)) hh["gsp-kwh"] = hh["laf"] * hh["msp-kwh"] hh["gsp-kw"] = hh["gsp-kwh"] * 2 if hh["ct-is-month-end"]: month_to = hh["start-date"] month_from = month_to - relativedelta(months=1) + HH days_in_month = 0 md_kva = 0 month_imp_kvarh = 0 month_kwh = 0 for dsc in ds.get_data_sources(month_from, month_to): for h in dsc.hh_data: if h["ct-decimal-hour"] == 0: days_in_month += 1 md_kva = max(md_kva, (h["msp-kw"] ** 2 + h["imp-msp-kvar"] ** 2) ** 0.5) month_imp_kvarh += h["imp-msp-kvarh"] month_kwh += h["msp-kwh"] tariff = get_file_rates(ds.caches, ds.dno_code, hh["start-date"])["tariffs"][ ds.llfc_code ] try: reactive_rate = float(tariff["reactive-gbp-per-kvarh"]) except KeyError as e: raise BadRequest(str(e)) hh["duos-reactive-rate"] = reactive_rate if not ds.is_displaced: hh["duos-availability-kva"] = ds.sc hh["duos-excess-availability-kva"] = max(md_kva - ds.sc, 0) for prefix in ["", "excess-"]: tariff_key = prefix + "gbp-per-kva-per-day" if tariff_key in tariff: rate_key = "duos-" + prefix + "availability-rate" hh[rate_key] = float(tariff[tariff_key]) hh["duos-" + prefix + "availability-days"] = days_in_month hh["duos-" + prefix + "availability-gbp"] = ( hh[rate_key] * hh["duos-" + prefix + "availability-kva"] * hh["duos-" + prefix + "availability-days"] ) hh["duos-reactive-gbp"] = ( max(0, month_imp_kvarh - month_kwh / 2) * reactive_rate )
def get_file_rates(self, contract_name, timestamp): return get_file_rates(self.caches, contract_name, timestamp)
def _process_hh(ds, rate_period, est_kw, hh): month_start, month_finish = next( c_months_u(start_year=hh["ct-year"], start_month=hh["ct-month"])) month_start_ct = to_ct(month_start) if month_start_ct.month > 3: year = month_start_ct.year else: year = month_start_ct.year - 1 financial_year_start = to_utc(ct_datetime(year, 4, 1)) last_financial_year_start = to_utc(ct_datetime(year - 1, 4, 1)) financial_year_finish = to_utc(ct_datetime(year + 1, 3, 31, 23, 30)) est_triad_kws = [] earliest_triad = None for dt in get_file_rates(ds.caches, "triad_dates", last_financial_year_start)["triad_dates"]: triad_hh = None earliest_triad = hh_min(earliest_triad, dt) try: d = next(ds.get_data_sources(dt, dt, financial_year_start)) chellow.duos.duos_vb(d) triad_hh = d.hh_data[0] while dt < financial_year_start: dt += relativedelta(years=1) for d in ds.get_data_sources(dt, dt, financial_year_start): chellow.duos.duos_vb(d) datum = d.hh_data[0] triad_hh["laf"] = datum["laf"] triad_hh["gsp-kw"] = datum["laf"] * triad_hh["msp-kw"] except StopIteration: triad_hh = { "hist-start": dt, "msp-kw": 0, "start-date": dt, "status": "before start of MPAN", "laf": 1, "gsp-kw": 0, } est_triad_kws.append(triad_hh) if ds.site is None: era = ds.supply.find_era_at(ds.sess, earliest_triad) if (era is None or era.get_channel(ds.sess, ds.is_import, "ACTIVE") is None and est_kw is None): est_kw = 0.85 * max(datum["msp-kwh"] for datum in ds.hh_data) * 2 if est_kw is not None: for est_datum in est_triad_kws: est_datum["msp-kw"] = est_kw est_datum["gsp-kw"] = est_datum["msp-kw"] * est_datum["laf"] gsp_kw = 0 for i, triad_hh in enumerate(est_triad_kws): triad_prefix = "triad-estimate-" + str(i + 1) hh[triad_prefix + "-date"] = triad_hh["hist-start"] hh[triad_prefix + "-msp-kw"] = triad_hh["msp-kw"] hh[triad_prefix + "-status"] = triad_hh["status"] hh[triad_prefix + "-laf"] = triad_hh["laf"] hh[triad_prefix + "-gsp-kw"] = triad_hh["gsp-kw"] gsp_kw += triad_hh["gsp-kw"] hh["triad-estimate-gsp-kw"] = gsp_kw / 3 polarity = "import" if ds.llfc.is_import else "export" gsp_group_code = ds.gsp_group_code rate = float( get_file_rates( ds.caches, "triad_rates", month_start)["triad_gbp_per_gsp_kw"][polarity][gsp_group_code]) hh["triad-estimate-rate"] = rate est_triad_gbp = hh["triad-estimate-rate"] * hh["triad-estimate-gsp-kw"] if rate_period == "monthly": total_intervals = 12 est_intervals = 1 hh["triad-estimate-months"] = est_intervals else: dt = financial_year_start total_intervals = 0 while dt <= financial_year_finish: total_intervals += 1 dt += relativedelta(days=1) est_intervals = 0 for d in ds.get_data_sources(month_start, month_finish): for h in d.hh_data: if h["ct-decimal-hour"] == 0: est_intervals += 1 hh["triad-estimate-days"] = est_intervals hh["triad-estimate-gbp"] = est_triad_gbp / total_intervals * est_intervals if hh["ct-month"] == 3: triad_kws = [] for t_date in get_file_rates(ds.caches, "triad_dates", month_start)["triad_dates"]: try: d = next(ds.get_data_sources(t_date, t_date)) if (ds.supplier_contract is None or d.supplier_contract == ds.supplier_contract): chellow.duos.duos_vb(d) thh = d.hh_data[0] else: thh = { "hist-start": t_date, "msp-kw": 0, "start-date": t_date, "status": "before contract", "laf": "before contract", "gsp-kw": 0, } except StopIteration: thh = { "hist-start": t_date, "msp-kw": 0, "start-date": t_date, "status": "before start of supply", "laf": "before start of supply", "gsp-kw": 0, } while t_date < financial_year_start: t_date += relativedelta(years=1) try: d = next(ds.get_data_sources(t_date, t_date)) if (ds.supplier_contract is None or d.supplier_contract == ds.supplier_contract): chellow.duos.duos_vb(d) thh["laf"] = d.hh_data[0]["laf"] thh["gsp-kw"] = thh["laf"] * thh["msp-kw"] except StopIteration: pass triad_kws.append(thh) gsp_kw = 0 for i, triad_hh in enumerate(triad_kws): pref = "triad-actual-" + str(i + 1) hh[pref + "-date"] = triad_hh["start-date"] hh[pref + "-msp-kw"] = triad_hh["msp-kw"] hh[pref + "-status"] = triad_hh["status"] hh[pref + "-laf"] = triad_hh["laf"] hh[pref + "-gsp-kw"] = triad_hh["gsp-kw"] gsp_kw += triad_hh["gsp-kw"] hh["triad-actual-gsp-kw"] = gsp_kw / 3 polarity = "import" if ds.llfc.is_import else "export" gsp_group_code = ds.gsp_group_code tot_rate = 0 for start_date, finish_date, script in get_file_scripts("triad_rates"): if start_date <= financial_year_finish and not hh_before( finish_date, financial_year_start): start_month = to_ct(start_date).month if start_month < 4: start_month += 12 if finish_date is None: finish_month = 3 else: finish_month = to_ct(finish_date).month if finish_month < 4: finish_month += 12 rt = get_file_rates( ds.caches, "triad_rates", start_date )["triad_gbp_per_gsp_kw"][polarity][gsp_group_code] tot_rate += (finish_month - start_month + 1) * float(rt) rate = tot_rate / 12 hh["triad-actual-rate"] = rate hh["triad-actual-gbp"] = hh["triad-actual-rate"] * hh[ "triad-actual-gsp-kw"] era = ds.supply.find_era_at(ds.sess, month_finish) est_intervals = 0 interval = (relativedelta( months=1) if rate_period == "monthly" else relativedelta(days=1)) dt = month_finish while era is not None and dt > financial_year_start: est_intervals += 1 dt -= interval if hh_after(dt, era.finish_date): era = ds.supply.find_era_at(ds.sess, dt) if rate_period == "monthly": hh["triad-all-estimates-months"] = est_intervals else: hh["triad-all-estimates-days"] = est_intervals hh["triad-all-estimates-gbp"] = (est_triad_gbp / total_intervals * est_intervals * -1)
def datum_2012_02_23(ds, hh): start_date = hh["start-date"] dno_cache = ds.caches["dno"][ds.dno_code] if not ds.full_channels and hh["msp-kwh"] == 0: imp_msp_kvarh, exp_msp_kvarh = 0, 0 else: imp_msp_kvarh, exp_msp_kvarh = hh["imp-msp-kvarh"], hh["exp-msp-kvarh"] try: gsp_group_cache = dno_cache[ds.gsp_group_code] except KeyError: gsp_group_cache = dno_cache[ds.gsp_group_code] = {} try: tariff = gsp_group_cache["tariffs"][ds.pc_code][ds.llfc_code][start_date] except KeyError: try: tariffs_cache = gsp_group_cache["tariffs"] except KeyError: tariffs_cache = gsp_group_cache["tariffs"] = {} try: pc_cache = tariffs_cache[ds.pc_code] except KeyError: pc_cache = tariffs_cache[ds.pc_code] = {} try: tariffs = pc_cache[ds.llfc_code] except KeyError: tariffs = pc_cache[ds.llfc_code] = {} try: tariff = tariffs[start_date] except KeyError: tariff = None try: tariff_list = get_file_rates(ds.caches, ds.dno_code, start_date)[ ds.gsp_group_code ]["tariffs"] except KeyError as e: raise BadRequest(str(e)) for llfcs_pcs, tf in tariff_list.items(): key = llfcs_pcs.split("_") llfcs = [v.strip() for v in key[0].split(",")] if len(key) == 2: pcs = [v.strip() for v in key[1].split(",")] else: pcs = None if ds.llfc_code in llfcs and (pcs is None or ds.pc_code in pcs): tariff = tf break if tariff is None: raise BadRequest( f"For the DNO {ds.dno_code} and timestamp {hh_format(start_date)} " f"and GSP group {ds.gsp_group_code}, the LLFC {ds.llfc_code} " f"with PC {ds.pc_code} can't be found in the 'tariffs' section." ) tariffs[start_date] = tariff try: band = gsp_group_cache["bands"][start_date] except KeyError: try: bands_cache = gsp_group_cache["bands"] except KeyError: bands_cache = gsp_group_cache["bands"] = {} try: band = bands_cache[start_date] except KeyError: band = "green" ct_hr = hh["ct-decimal-hour"] weekend = hh["ct-day-of-week"] > 4 try: slots = get_file_rates(ds.caches, ds.dno_code, start_date)[ ds.gsp_group_code ]["bands"] except KeyError as e: raise BadRequest(str(e)) for slot in slots: slot_weekend = slot["weekend"] == 1 if slot_weekend == weekend and slot["start"] <= ct_hr < slot["finish"]: band = slot["band"] break bands_cache[start_date] = band try: laf = dno_cache["lafs"][ds.llfc_code][start_date] except KeyError: try: laf_cache = dno_cache["lafs"] except KeyError: laf_cache = dno_cache["lafs"] = {} try: laf_cache_llfc = laf_cache[ds.llfc_code] except KeyError: laf_cache_llfc = laf_cache[ds.llfc_code] = {} try: laf = laf_cache_llfc[start_date] except KeyError: rs = get_file_rates(ds.caches, "lafs_" + ds.dno_code, start_date) hist_date = rs["hist_dates"][start_date] try: hist_map_llfcs = rs._storage["hist_map"] except KeyError: hist_map_llfcs = rs._storage["hist_map"] = {} try: hist_map = hist_map_llfcs[ds.llfc_code] except KeyError: hist_map = hist_map_llfcs[ds.llfc_code] = {} try: laf = hist_map[hist_date] except KeyError: try: tp_id = rs["llfc_tp"][ds.llfc_code] except KeyError as e: raise BadRequest(str(e)) for chunk in rs["tps"][tp_id].values(): chunk_start_raw = Datetime.strptime(chunk["start_date"], "%Y%m%d") chunk_finish_raw = Datetime.strptime(chunk["finish_date"], "%Y%m%d") day_start_raw = chunk_start_raw while day_start_raw <= chunk_finish_raw: day_start_ct = to_ct(day_start_raw) day_start = to_utc(day_start_ct) for slot in chunk["slots"]: for i in range(slot["slot_start"] - 1, slot["slot_finish"]): dt = day_start + Timedelta(minutes=30 * i) hist_map[dt] = float(slot["laf"]) day_start_raw += Timedelta(days=1) laf = hist_map[hist_date] laf_cache_llfc[start_date] = laf hh["laf"] = laf hh["gsp-kwh"] = laf * hh["msp-kwh"] hh["gsp-kw"] = hh["gsp-kwh"] * 2 kvarh = max( max(imp_msp_kvarh, exp_msp_kvarh) - (0.95 ** -2 - 1) ** 0.5 * hh["msp-kwh"], 0 ) hh["duos-reactive-kvarh"] = kvarh duos_reactive_rate = tariff["gbp-per-kvarh"] if duos_reactive_rate is not None: duos_reactive_rate = float(duos_reactive_rate) if duos_reactive_rate != 0: hh["duos-reactive-rate"] = duos_reactive_rate hh["duos-reactive-gbp"] = kvarh * duos_reactive_rate rate = float(tariff[KEYS[band]["tariff-rate"]]) hh[KEYS[band]["bill-rate"]] = rate hh[KEYS[band]["kwh"]] = hh["msp-kwh"] hh[KEYS[band]["gbp"]] = rate * hh["msp-kwh"] if hh["ct-decimal-hour"] == 23.5 and not ds.is_displaced: hh["duos-fixed-days"] = 1 rate = float(tariff["gbp-per-mpan-per-day"]) hh["duos-fixed-rate"] = rate hh["duos-fixed-gbp"] = rate hh["duos-availability-days"] = 1 kva = ds.sc hh["duos-availability-kva"] = kva rate = float(tariff["gbp-per-kva-per-day"]) hh["duos-availability-rate"] = rate hh["duos-availability-gbp"] = rate * kva if hh["ct-is-month-end"] and not ds.is_displaced: month_to = start_date month_from = to_utc(ct_datetime(hh["ct-year"], hh["ct-month"], 1)) md_kva = 0 days_in_month = 0 for dsc in ds.get_data_sources(month_from, month_to): for datum in dsc.hh_data: md_kva = max( md_kva, ( datum["msp-kw"] ** 2 + max(datum["imp-msp-kvar"], datum["exp-msp-kvar"]) ** 2 ) ** 0.5, ) if datum["ct-decimal-hour"] == 0: days_in_month += 1 excess_kva = max(md_kva - ds.sc, 0) if "excess-gbp-per-kva-per-day" in tariff and excess_kva != 0: rate = float(tariff["excess-gbp-per-kva-per-day"]) hh["duos-excess-availability-kva"] = excess_kva rate = float(tariff["excess-gbp-per-kva-per-day"]) hh["duos-excess-availability-rate"] = rate hh["duos-excess-availability-days"] = days_in_month hh["duos-excess-availability-gbp"] = rate * excess_kva * days_in_month
def __init__(self, sess, start_date, finish_date, forecast_date, g_era, caches, g_bill): self.sess = sess self.caches = caches self.forecast_date = forecast_date self.start_date = start_date self.finish_date = finish_date times = get_times(sess, caches, start_date, finish_date, forecast_date) self.years_back = times['years-back'] self.history_start = times['history-start'] self.history_finish = times['history-finish'] self.problem = '' self.bill = defaultdict(int, {'problem': ''}) self.hh_data = [] self.rate_sets = defaultdict(set) self.g_bill = g_bill if self.g_bill is not None: self.g_bill_start = g_bill.start_date self.g_bill_finish = g_bill.finish_date self.is_last_g_bill_gen = \ not self.g_bill_finish < self.start_date and not \ self.g_bill_finish > self.finish_date self.g_era = g_era self.g_supply = g_era.g_supply self.mprn = self.g_supply.mprn self.g_exit_zone_code = self.g_supply.g_exit_zone.code self.g_ldz_code = self.g_supply.g_exit_zone.g_ldz.code self.g_dn_code = self.g_supply.g_exit_zone.g_ldz.g_dn.code self.account = g_era.account self.g_contract = g_era.g_contract self.consumption_info = '' if self.years_back == 0: hist_g_eras = [self.g_era] else: hist_g_eras = sess.query(GEra).filter( GEra.g_supply == self.g_supply, GEra.start_date <= self.history_finish, or_(GEra.finish_date == null(), GEra.finish_date >= self.history_start)).order_by( GEra.start_date).all() if len(hist_g_eras) == 0: hist_g_eras = sess.query(GEra).filter( GEra.g_supply == self.g_supply).order_by( GEra.start_date).limit(1).all() g_cv_id = get_non_core_contract_id('g_cv') hist_map = {} for i, hist_g_era in enumerate(hist_g_eras): if self.history_start > hist_g_era.start_date: chunk_start = self.history_start else: if i == 0: chunk_start = self.history_start else: chunk_start = hist_g_era.start_date chunk_finish = hh_min(hist_g_era.finish_date, self.history_finish) if self.g_bill is None: read_list = [] read_keys = set() pairs = [] prior_pres_g_reads = iter( sess.query(GRegisterRead).join(GBill).join(BillType).join( GRegisterRead.pres_type).filter( GReadType.code.in_(ACTUAL_READ_TYPES), GBill.g_supply == self.g_supply, GRegisterRead.pres_date < chunk_start, BillType.code != 'W').order_by( GRegisterRead.pres_date.desc())) prior_prev_g_reads = iter( sess.query(GRegisterRead).join(GBill).join(BillType).join( GRegisterRead.prev_type).filter( GReadType.code.in_(ACTUAL_READ_TYPES), GBill.g_supply == self.g_supply, GRegisterRead.prev_date < chunk_start, BillType.code != 'W').order_by( GRegisterRead.prev_date.desc())) next_pres_g_reads = iter( sess.query(GRegisterRead).join(GBill).join(BillType).join( GRegisterRead.pres_type).filter( GReadType.code.in_(ACTUAL_READ_TYPES), GBill.g_supply == self.g_supply, GRegisterRead.pres_date >= chunk_start, BillType.code != 'W').order_by( GRegisterRead.pres_date)) next_prev_g_reads = iter( sess.query(GRegisterRead).join(GBill).join(BillType).join( GRegisterRead.prev_type).filter( GReadType.code.in_(ACTUAL_READ_TYPES), GBill.g_supply == self.g_supply, GRegisterRead.prev_date >= chunk_start, BillType.code != 'W').order_by( GRegisterRead.prev_date)) for is_forwards in (False, True): if is_forwards: pres_g_reads = next_pres_g_reads prev_g_reads = next_prev_g_reads read_list.reverse() else: pres_g_reads = prior_pres_g_reads prev_g_reads = prior_prev_g_reads prime_pres_g_read = None prime_prev_g_read = None while True: while prime_pres_g_read is None: try: pres_g_read = next(pres_g_reads) except StopIteration: break pres_date = pres_g_read.pres_date pres_msn = pres_g_read.msn read_key = '_'.join([str(pres_date), pres_msn]) if read_key in read_keys: continue pres_g_bill = sess.query(GBill).join( BillType).filter( GBill.g_supply == self.g_supply, GBill.finish_date >= pres_g_read.g_bill.start_date, GBill.start_date <= pres_g_read.g_bill.finish_date, BillType.code != 'W').order_by( GBill.issue_date.desc(), BillType.code).first() if pres_g_bill != pres_g_read.g_bill: continue value = sess.query( cast(GRegisterRead.pres_value, Float)).filter( GRegisterRead.g_bill == pres_g_bill, GRegisterRead.pres_date == pres_date, GRegisterRead.msn == pres_msn).scalar() prime_pres_g_read = { 'date': pres_date, 'value': value, 'msn': pres_msn } read_keys.add(read_key) while prime_prev_g_read is None: try: prev_g_read = next(prev_g_reads) except StopIteration: break prev_date = prev_g_read.prev_date prev_msn = prev_g_read.msn read_key = '_'.join([str(prev_date), prev_msn]) if read_key in read_keys: continue prev_g_bill = sess.query(GBill).join( BillType).filter( GBill.g_supply == self.g_supply, GBill.finish_date >= prev_g_read.g_bill.start_date, GBill.start_date <= prev_g_read.g_bill.finish_date, BillType.code != 'W').order_by( GBill.issue_date.desc(), BillType.code).first() if prev_g_bill != prev_g_read.g_bill: continue value = sess.query( cast(GRegisterRead.prev_value, Float)).filter( GRegisterRead.g_bill == prev_g_bill, GRegisterRead.prev_date == prev_date, GRegisterRead.msn == prev_msn).scalar() prime_prev_g_read = { 'date': prev_date, 'value': value, 'msn': prev_msn } read_keys.add(read_key) if prime_pres_g_read is None and \ prime_prev_g_read is None: break elif prime_pres_g_read is None: read_list.append(prime_prev_g_read) prime_prev_g_read = None elif prime_prev_g_read is None: read_list.append(prime_pres_g_read) prime_pres_g_read = None else: if is_forwards: if prime_prev_g_read['date'] == \ prime_pres_g_read['date'] or \ prime_pres_g_read['date'] < \ prime_prev_g_read['date']: read_list.append(prime_pres_g_read) prime_pres_g_read = None else: read_list.append(prime_prev_g_read) prime_prev_g_read = None else: if prime_prev_g_read['date'] == \ prime_pres_g_read['date'] or \ prime_prev_g_read['date'] > \ prime_pres_g_read['date']: read_list.append(prime_prev_g_read) prime_prev_g_read = None else: read_list.append(prime_pres_g_read) prime_pres_g_read = None if len(read_list) > 1: if is_forwards: aft_read = read_list[-2] fore_read = read_list[-1] else: aft_read = read_list[-1] fore_read = read_list[-2] if aft_read['msn'] == fore_read['msn']: num_hh = (fore_read['date'] - aft_read['date'] ).total_seconds() / (30 * 60) units = fore_read['value'] - aft_read['value'] if units < 0: digits = int(math.log10( aft_read['value'])) + 1 units = 10**digits + units pairs.append({ 'start-date': aft_read['date'], 'units': units / num_hh }) if not is_forwards or ( is_forwards and read_list[-1]['date'] > chunk_finish): break self.consumption_info += 'read list - \n' + dumps(read_list) \ + "\n" hhs = _find_hhs(sess, caches, hist_g_era, pairs, chunk_start, chunk_finish, g_cv_id, self.g_ldz_code) hist_map.update(hhs) self.consumption_info += 'pairs - \n' + dumps(pairs) else: g_bills = [] for cand_bill in sess.query(GBill).join(GBatch) \ .join(BillType).filter( GBill.g_supply == self.g_supply, GBill.g_reads.any(), GBatch.g_contract == self.g_contract, GBill.start_date <= chunk_finish, GBill.finish_date >= chunk_start, BillType.code != 'W').order_by( GBill.issue_date.desc(), GBill.start_date): can_insert = True for g_bill in g_bills: if not cand_bill.start_date > g_bill.finish_date \ and not cand_bill.finish_date < \ g_bill.start_date: can_insert = False break if can_insert: g_bills.append(cand_bill) for g_bill in g_bills: units_consumed = 0 for prev_value, pres_value in sess.query( cast(GRegisterRead.prev_value, Float), cast( GRegisterRead.pres_value, Float)).filter(GRegisterRead.g_bill == g_bill): units_diff = pres_value - prev_value if units_diff < 0: total_units = 10**len(str(int(prev_value))) c_units = total_units - prev_value + pres_value if c_units < abs(units_diff): units_diff = c_units units_consumed += units_diff bill_s = (g_bill.finish_date - g_bill.start_date + timedelta(minutes=30)).total_seconds() hh_units_consumed = units_consumed / (bill_s / (60 * 30)) cf = float(hist_g_era.correction_factor) g_unit = hist_g_era.g_unit unit_code, unit_factor = g_unit.code, float(g_unit.factor) for hh_date in hh_range(caches, g_bill.start_date, g_bill.finish_date): cv, avg_cv = find_cv(sess, caches, g_cv_id, hh_date, self.g_ldz_code) hist_map[hh_date] = { 'unit_code': unit_code, 'unit_factor': unit_factor, 'units_consumed': hh_units_consumed, 'correction_factor': cf, 'calorific_value': cv, 'avg_cv': avg_cv } for d in datum_range(sess, self.caches, self.years_back, start_date, finish_date): h = d.copy() hist_start = h['hist_start'] h.update(hist_map.get(hist_start, {})) h['kwh'] = h['units_consumed'] * h['unit_factor'] * \ h['correction_factor'] * h['calorific_value'] / 3.6 h['kwh_avg'] = h['units_consumed'] * h['unit_factor'] * \ h['correction_factor'] * h['avg_cv'] / 3.6 h['ug_rate'] = float( get_file_rates( self.caches, 'g_ug', h['start_date'])['ug_gbp_per_kwh'][self.g_exit_zone_code]) self.hh_data.append(h)
def hh(data_source, rate_period='monthly', est_kw=None): for hh in (h for h in data_source.hh_data if h['ct-is-month-end']): hh_start = hh['start-date'] month_start = utc_datetime(hh_start.year, hh_start.month) month_finish = month_start + relativedelta(months=1) - HH financial_year_start = month_start while financial_year_start.month != 4: financial_year_start -= relativedelta(months=1) last_financial_year_start = financial_year_start - relativedelta( years=1) financial_year_finish = financial_year_start + relativedelta( years=1) - HH est_triad_kws = [] earliest_triad = None for dt in get_file_rates( data_source.caches, 'triad_dates', last_financial_year_start)['triad_dates']: triad_hh = None earliest_triad = hh_min(earliest_triad, dt) try: ds = next( data_source.get_data_sources(dt, dt, financial_year_start)) chellow.duos.duos_vb(ds) triad_hh = ds.hh_data[0] while dt < financial_year_start: dt += relativedelta(years=1) for ds in data_source.get_data_sources( dt, dt, financial_year_start): chellow.duos.duos_vb(ds) datum = ds.hh_data[0] triad_hh['laf'] = datum['laf'] triad_hh['gsp-kw'] = datum['laf'] * triad_hh['msp-kw'] except StopIteration: triad_hh = { 'hist-start': dt, 'msp-kw': 0, 'start-date': dt, 'status': 'before start of MPAN', 'laf': 1, 'gsp-kw': 0} est_triad_kws.append(triad_hh) if data_source.site is None: era = data_source.supply.find_era_at( data_source.sess, earliest_triad) if era is None or era.get_channel( data_source.sess, data_source.is_import, 'ACTIVE') is None: if est_kw is not None: est_triad_kw = est_kw else: est_triad_kw = 0.85 * max( datum['msp-kwh'] for datum in data_source.hh_data) * 2 for est_datum in est_triad_kws: est_datum['msp-kw'] = est_triad_kw est_datum['gsp-kw'] = est_datum['msp-kw'] * \ est_datum['laf'] gsp_kw = 0 for i, triad_hh in enumerate(est_triad_kws): triad_prefix = 'triad-estimate-' + str(i + 1) hh[triad_prefix + '-date'] = triad_hh['hist-start'] hh[triad_prefix + '-msp-kw'] = triad_hh['msp-kw'] hh[triad_prefix + '-status'] = triad_hh['status'] hh[triad_prefix + '-laf'] = triad_hh['laf'] hh[triad_prefix + '-gsp-kw'] = triad_hh['gsp-kw'] gsp_kw += triad_hh['gsp-kw'] hh['triad-estimate-gsp-kw'] = gsp_kw / 3 polarity = 'import' if data_source.llfc.is_import else 'export' gsp_group_code = data_source.gsp_group_code rate = float( get_file_rates( data_source.caches, 'triad_rates', month_start)['triad_gbp_per_gsp_kw'][polarity][gsp_group_code]) hh['triad-estimate-rate'] = rate est_triad_gbp = hh['triad-estimate-rate'] * hh['triad-estimate-gsp-kw'] if rate_period == 'monthly': total_intervals = 12 est_intervals = 1 hh['triad-estimate-months'] = est_intervals else: dt = financial_year_start total_intervals = 0 while dt <= financial_year_finish: total_intervals += 1 dt += relativedelta(days=1) est_intervals = 0 for ds in data_source.get_data_sources(month_start, month_finish): for h in ds.hh_data: if h['utc-decimal-hour'] == 0: est_intervals += 1 hh['triad-estimate-days'] = est_intervals hh['triad-estimate-gbp'] = est_triad_gbp / total_intervals * \ est_intervals if month_start.month == 3: triad_kws = [] for t_date in get_file_rates( data_source.caches, 'triad_dates', month_start)['triad_dates']: try: ds = next(data_source.get_data_sources(t_date, t_date)) if data_source.supplier_contract is None or \ ds.supplier_contract == \ data_source.supplier_contract: chellow.duos.duos_vb(ds) thh = ds.hh_data[0] else: thh = { 'hist-start': t_date, 'msp-kw': 0, 'start-date': t_date, 'status': 'before contract', 'laf': 'before contract', 'gsp-kw': 0} except StopIteration: thh = { 'hist-start': t_date, 'msp-kw': 0, 'start-date': t_date, 'status': 'before start of supply', 'laf': 'before start of supply', 'gsp-kw': 0} while t_date < financial_year_start: t_date += relativedelta(years=1) try: ds = next(data_source.get_data_sources(t_date, t_date)) if data_source.supplier_contract is None or \ ds.supplier_contract == \ data_source.supplier_contract: chellow.duos.duos_vb(ds) thh['laf'] = ds.hh_data[0]['laf'] thh['gsp-kw'] = thh['laf'] * thh['msp-kw'] except StopIteration: pass triad_kws.append(thh) gsp_kw = 0 for i, triad_hh in enumerate(triad_kws): pref = 'triad-actual-' + str(i + 1) hh[pref + '-date'] = triad_hh['start-date'] hh[pref + '-msp-kw'] = triad_hh['msp-kw'] hh[pref + '-status'] = triad_hh['status'] hh[pref + '-laf'] = triad_hh['laf'] hh[pref + '-gsp-kw'] = triad_hh['gsp-kw'] gsp_kw += triad_hh['gsp-kw'] hh['triad-actual-gsp-kw'] = gsp_kw / 3 polarity = 'import' if data_source.llfc.is_import else 'export' gsp_group_code = data_source.gsp_group_code tot_rate = 0 for start_date, finish_date, script in get_file_scripts( 'triad_rates'): if start_date <= financial_year_finish and not hh_before( finish_date, financial_year_start): start_month = start_date.month if start_month < 4: start_month += 12 if finish_date is None: finish_month = financial_year_finish.month else: finish_month = finish_date.month if finish_month < 4: finish_month += 12 rt = get_file_rates( data_source.caches, 'triad_rates', start_date )['triad_gbp_per_gsp_kw'][polarity][gsp_group_code] tot_rate += (finish_month - start_month + 1) * float(rt) rate = tot_rate / 12 hh['triad-actual-rate'] = rate hh['triad-actual-gbp'] = hh['triad-actual-rate'] * \ hh['triad-actual-gsp-kw'] era = data_source.supply.find_era_at( data_source.sess, month_finish) est_intervals = 0 interval = relativedelta(months=1) if \ rate_period == 'monthly' else relativedelta(days=1) dt = month_finish while era is not None and dt > financial_year_start: est_intervals += 1 dt -= interval if hh_after(dt, era.finish_date): era = data_source.supply.find_era_at(data_source.sess, dt) if rate_period == 'monthly': hh['triad-all-estimates-months'] = est_intervals else: hh['triad-all-estimates-days'] = est_intervals hh['triad-all-estimates-gbp'] = est_triad_gbp / \ total_intervals * est_intervals * -1
def __init__( self, sess, start_date, finish_date, forecast_date, g_era, caches, g_bill ): self.sess = sess self.caches = caches self.forecast_date = forecast_date self.start_date = start_date self.finish_date = finish_date self.bill_hhs = {} times = get_times(sess, caches, start_date, finish_date, forecast_date) self.years_back = times["years-back"] self.history_start = times["history-start"] self.history_finish = times["history-finish"] self.problem = "" self.bill = defaultdict(int, {"problem": ""}) self.hh_data = [] self.rate_sets = defaultdict(set) self.g_bill = g_bill if self.g_bill is not None: self.g_bill_start = g_bill.start_date self.g_bill_finish = g_bill.finish_date self.is_last_g_bill_gen = ( not self.g_bill_finish < self.start_date and not self.g_bill_finish > self.finish_date ) self.g_era = g_era self.g_supply = g_era.g_supply self.mprn = self.g_supply.mprn self.g_exit_zone_code = self.g_supply.g_exit_zone.code self.g_ldz_code = self.g_supply.g_exit_zone.g_ldz.code self.g_dn_code = self.g_supply.g_exit_zone.g_ldz.g_dn.code self.account = g_era.account self.g_reading_frequency = g_era.g_reading_frequency self.g_reading_frequency_code = self.g_reading_frequency.code self.g_contract = g_era.g_contract self.consumption_info = "" if self.years_back == 0: hist_g_eras = [self.g_era] else: hist_g_eras = ( sess.query(GEra) .filter( GEra.g_supply == self.g_supply, GEra.start_date <= self.history_finish, or_( GEra.finish_date == null(), GEra.finish_date >= self.history_start, ), ) .order_by(GEra.start_date) .all() ) if len(hist_g_eras) == 0: hist_g_eras = ( sess.query(GEra) .filter(GEra.g_supply == self.g_supply) .order_by(GEra.start_date) .limit(1) .all() ) g_cv_id = get_non_core_contract_id("g_cv") hist_map = {} for i, hist_g_era in enumerate(hist_g_eras): if self.history_start > hist_g_era.start_date: chunk_start = self.history_start else: if i == 0: chunk_start = self.history_start else: chunk_start = hist_g_era.start_date chunk_finish = hh_min(hist_g_era.finish_date, self.history_finish) if self.g_bill is None: self.consumption_info += _no_bill_kwh( sess, caches, self.g_supply, chunk_start, chunk_finish, hist_g_era, g_cv_id, self.g_ldz_code, hist_map, forecast_date, ) else: _bill_kwh( sess, self.caches, self.g_supply, hist_g_era, chunk_start, chunk_finish, g_cv_id, hist_map, self.g_ldz_code, ) for d in datum_range( sess, self.caches, self.years_back, start_date, finish_date ): h = d.copy() hist_start = h["hist_start"] h.update(hist_map.get(hist_start, {})) h["kwh"] = ( h["units_consumed"] * h["unit_factor"] * h["correction_factor"] * h["calorific_value"] / 3.6 ) h["kwh_avg"] = ( h["units_consumed"] * h["unit_factor"] * h["correction_factor"] * h["avg_cv"] / 3.6 ) h["ug_rate"] = float( get_file_rates(self.caches, "g_ug", h["start_date"])["ug_gbp_per_kwh"][ self.g_exit_zone_code ] ) self.hh_data.append(h) self.bill_hhs[d["start_date"]] = {}
def vb(ds): to_exit_commodity_rate_set = ds.rate_sets['to_exit_commodity_rate'] so_exit_commodity_rate_set = ds.rate_sets['so_exit_commodity_rate'] dn_system_commodity_rate_set = ds.rate_sets['dn_system_commodity_rate'] dn_system_capacity_rate_set = ds.rate_sets['dn_system_capacity_rate'] dn_system_capacity_fixed_rate_set = ds.rate_sets[ 'dn_system_capacity_fixed_rate'] dn_customer_capacity_rate_set = ds.rate_sets['dn_customer_capacity_rate'] dn_customer_capacity_fixed_rate_set = ds.rate_sets[ 'dn_customer_capacity_fixed_rate'] dn_customer_fixed_rate_set = ds.rate_sets['dn_customer_fixed_rate'] dn_ecn_rate_set = ds.rate_sets['dn_ecn_rate'] dn_ecn_fixed_rate_set = ds.rate_sets['dn_ecn_fixed_rate'] for hh in ds.hh_data: soq = hh['soq'] aq = hh['aq'] nts_rates = get_file_rates(ds.caches, 'g_nts_commodity', hh['start_date']) to_exit_commodity_rate = float(nts_rates['to_exit_gbp_per_kwh']) to_exit_commodity_rate_set.add(to_exit_commodity_rate) hh['to_exit_commodity_rate'] = to_exit_commodity_rate so_exit_commodity_rate = float(nts_rates['so_exit_gbp_per_kwh']) so_exit_commodity_rate_set.add(so_exit_commodity_rate) hh['so_exit_commodity_rate'] = so_exit_commodity_rate rates = get_file_rates(ds.caches, 'g_dn', hh['start_date']) dn_rates = rates['gdn'][ds.g_dn_code] system_commodity_rates = dn_rates['system_commodity'] system_capacity_rates = dn_rates['system_capacity'] customer_capacity_rates = dn_rates['customer_capacity'] customer_fixed_rates = dn_rates['customer_fixed'] if aq <= 73200: pref = 'to_73200_' dn_system_commodity_rate = float( system_commodity_rates[pref + 'gbp_per_kwh']) dn_system_capacity_rate = float( system_capacity_rates[pref + 'gbp_per_kwh_per_day']) dn_customer_capacity_rate = float( customer_capacity_rates[pref + 'gbp_per_kwh_per_day']) dn_customer_fixed_rate = 0 elif 73200 < aq < 732000: pref = '73200_to_732000_' dn_system_commodity_rate = float( system_commodity_rates[pref + 'gbp_per_kwh']) dn_system_capacity_rate = float( system_capacity_rates[pref + 'gbp_per_kwh_per_day']) dn_customer_capacity_rate = float( customer_capacity_rates[pref + 'gbp_per_kwh_per_day']) if aq < 293000: dn_customer_fixed_rate = float( customer_fixed_rates[pref + "biannual_gbp_per_day"]) else: dn_customer_fixed_rate = float( customer_fixed_rates[pref + "monthly_gbp_per_day"]) else: key = '732000_and_over' system_commodity_rts = system_commodity_rates[key] dn_system_commodity_rate = max( float(system_commodity_rts['minimum_gbp_per_kwh']), float(system_commodity_rts['gbp_per_kwh']) * soq**float(system_commodity_rts['exponent'])) system_capacity_rts = system_capacity_rates[key] dn_system_capacity_rate = max( float(system_capacity_rts['minimum_gbp_per_kwh_per_day']), float(system_capacity_rts['gbp_per_kwh_per_day']) * soq**float(system_capacity_rts['exponent'])) customer_capacity_rts = customer_capacity_rates[key] dn_customer_capacity_rate = float( customer_capacity_rts['gbp_per_kwh_per_day']) * soq**float( customer_capacity_rts['exponent']) dn_customer_fixed_rate = 0 dn_system_commodity_rate_set.add(dn_system_commodity_rate) hh['dn_system_commodity_rate'] = dn_system_commodity_rate dn_system_capacity_rate_set.add(dn_system_capacity_rate) hh['dn_system_capacity_rate'] = dn_system_capacity_rate dn_system_capacity_fixed_rate = soq * dn_system_capacity_rate dn_system_capacity_fixed_rate_set.add(dn_system_capacity_fixed_rate) hh['dn_system_capacity_fixed_rate'] = dn_system_capacity_fixed_rate dn_customer_capacity_rate_set.add(dn_customer_capacity_rate) hh['dn_customer_capacity_rate'] = dn_customer_capacity_rate dn_customer_capacity_fixed_rate = soq * dn_customer_capacity_rate dn_customer_capacity_fixed_rate_set.add( dn_customer_capacity_fixed_rate) hh['dn_customer_capacity_fixed_rate'] = dn_customer_capacity_fixed_rate dn_customer_fixed_rate_set.add(dn_customer_fixed_rate) hh['dn_customer_fixed_rate'] = dn_customer_fixed_rate dn_ecn_rate = float(rates['exit_zones'][ds.g_exit_zone_code] ['exit_capacity_gbp_per_kwh_per_day']) dn_ecn_rate_set.add(dn_ecn_rate) hh['dn_ecn_rate'] = dn_ecn_rate dn_ecn_fixed_rate = dn_ecn_rate * soq dn_ecn_fixed_rate_set.add(dn_ecn_fixed_rate) hh['dn_ecn_fixed_rate'] = dn_ecn_fixed_rate
def datum_beginning_14(ds, hh): rates = get_file_rates(ds.caches, ds.dno_code, hh["start-date"]) try: tariff = rates["tariffs"][ds.llfc_code] except KeyError as e: raise BadRequest(str(e)) if 0 < hh["ct-decimal-hour"] <= 7: hh["duos-night-kwh"] = hh["msp-kwh"] hh["duos-night-gbp"] = hh["msp-kwh"] * float(tariff["night-gbp-per-kwh"]) else: hh["duos-day-kwh"] = hh["msp-kwh"] hh["duos-day-gbp"] = hh["msp-kwh"] * float(tariff["day-gbp-per-kwh"]) if 0 < hh["ct-decimal-hour"] <= 7: slot = "night" elif ( hh["ct-day-of-week"] < 5 and hh["ct-decimal-hour"] > 15.5 and hh["ct-decimal-hour"] < 19 and (hh["ct-month"] > 11 or hh["ct-month"] < 4) ): slot = "winter-weekday-peak" elif ( hh["ct-day-of-week"] < 5 and (7 <= hh["ct-decimal-hour"] < 16 or 18 < hh["ct-decimal-hour"] < 20) and (hh["ct-month"] > 11 or hh["ct-month"] < 4) ): slot = "winter-weekday-day" else: slot = "other" hh["laf"] = float(rates["lafs"][ds.voltage_level_code.lower()][slot]) hh["gsp-kwh"] = hh["msp-kwh"] * hh["laf"] hh["gsp-kw"] = hh["gsp-kwh"] * 2 if hh["utc-decimal-hour"] == 0: hh["duos-standing-gbp"] = float(tariff["fixed-gbp-per-day"]) if hh["ct-is-month-end"]: month_to = hh["start-date"] month_from = month_to - relativedelta(months=1) + HH availability = ds.sc reactive_rate = float(tariff["reactive-gbp-per-kvarh"]) hh["duos-reactive-rate"] = reactive_rate imp_msp_kvarh = 0 msp_kwh = 0 md_kva = 0 for dsc in ds.get_data_sources(month_from, month_to): for h in dsc.hh_data: imp_msp_kvarh += h["imp-msp-kvarh"] msp_kwh += h["msp-kwh"] md_kva = max( md_kva, (h["msp-kw"] ** 2 + (h["imp-msp-kvar"] + h["exp-msp-kvar"]) ** 2) ** 0.5, ) hh["duos-reactive-gbp"] = max(0, imp_msp_kvarh - msp_kwh / 3) * reactive_rate if not ds.is_displaced: availability_rate = float(tariff["availability-gbp-per-kva-per-day"]) hh["duos-availability-rate"] = availability_rate billed_avail = max(availability, md_kva) hh["duos-availability-gbp"] = availability_rate * billed_avail hh["duos-availability-agreed-kva"] = ds.sc hh["duos-availability-billed-kva"] = billed_avail
def datum_beginning_20(ds, hh): tariff = None for k, tf in get_file_rates(ds.caches, ds.dno_code, hh["start-date"])[ "tariffs" ].items(): if ds.llfc_code in [cd.strip() for cd in k.split(",")]: tariff = tf if tariff is None: raise BadRequest( "The tariff for the LLFC " + ds.llfc_code + " cannot be found for the DNO 20 at " + hh_format(hh["start-date"]) + "." ) lafs = get_file_rates(ds.caches, ds.dno_code, hh["start-date"])["lafs"][ ds.voltage_level_code.lower() ] try: day_rate = float(tariff["day-gbp-per-kwh"]) except KeyError as e: raise BadRequest(str(e)) if "night-gbp-per-kwh" in tariff: night_rate = float(tariff["night-gbp-per-kwh"]) if 0 < hh["ct-decimal-hour"] <= 7: hh["duos-night-kwh"] = hh["msp-kwh"] hh["duos-night-gbp"] = hh["msp-kwh"] * night_rate else: hh["duos-day-kwh"] = hh["msp-kwh"] hh["duos-day-gbp"] = hh["msp-kwh"] * day_rate else: hh["duos-day-kwh"] = hh["msp-kwh"] hh["duos-day-gbp"] = hh["msp-kwh"] * day_rate if 0 < hh["ct-decimal-hour"] <= 7: slot_name = "night" elif ( hh["ct-day-of-week"] < 5 and 16 < hh["ct-decimal-hour"] <= 19 and (hh["ct-month"] > 10 or hh["ct-month"] < 3) ): slot_name = "peak" elif ( 7 > hh["ct-day-of-week"] > 1 and (7 < hh["ct-decimal-hour"] < 15 or 18.5 < hh["ct-decimal-hour"] < 19) and (hh["ct-month"] > 11 or hh["ct-month"] < 4) ): slot_name = "winter-weekday" else: slot_name = "other" hh["laf"] = float(lafs[slot_name]) hh["gsp-kwh"] = hh["laf"] * hh["msp-kwh"] hh["gsp-kw"] = hh["gsp-kwh"] * 2 if hh["ct-is-month-end"]: tariff = None for k, tf in get_file_rates(ds.caches, ds.dno_code, hh["start-date"])[ "tariffs" ].items(): if ds.llfc_code in map(str.strip, k.split(",")): tariff = tf break if tariff is None: raise BadRequest( "The tariff for the LLFC " + ds.llfc_code + " cannot be found for the DNO 20 at " + hh_format(hh["start-date"]) + "." ) if not ds.is_displaced: year_md_kva_095 = year_md_095(ds, ds.finish_date) hh["duos-excess-availability-kva"] = max(year_md_kva_095 - ds.sc, 0) billed_avail = max(ds.sc, year_md_kva_095) hh["duos-availability-kva"] = ds.sc for threshold, block in [ (15, 15), (100, 5), (250, 10), (500, 25), (1000, 50), (None, 100), ]: if threshold is None or billed_avail < threshold: if billed_avail % block > 0: billed_avail = (int(billed_avail / block) + 1) * block break try: le_200_avail_rate = float( tariff["capacity-<=200-gbp-per-kva-per-month"] ) except KeyError as e: raise BadRequest(str(e)) hh["duos-availability-gbp"] = min(200, billed_avail) * le_200_avail_rate if billed_avail > 200: try: gt_200_avail_rate = float( tariff["capacity->200-gbp-per-kva-per-month"] ) except KeyError as e: raise BadRequest(str(e)) hh["duos-availability-gbp"] += (billed_avail - 200) * gt_200_avail_rate try: if "fixed-gbp-per-month" in tariff: hh["duos-standing-gbp"] = float(tariff["fixed-gbp-per-month"]) else: hh["duos-standing-gbp"] = ( float(tariff["fixed-gbp-per-day"]) * hh["utc-day"] ) except KeyError as e: raise BadRequest(str(e))
def datum_2012_02_23(ds, hh): start_date = hh["start-date"] dno_cache = ds.caches["dno"][ds.dno_code] if not ds.full_channels and hh["msp-kwh"] == 0: imp_msp_kvarh, exp_msp_kvarh = 0, 0 else: imp_msp_kvarh, exp_msp_kvarh = hh["imp-msp-kvarh"], hh["exp-msp-kvarh"] try: gsp_group_cache = dno_cache[ds.gsp_group_code] except KeyError: gsp_group_cache = dno_cache[ds.gsp_group_code] = {} try: tariff = gsp_group_cache["tariffs"][ds.pc_code][ds.llfc_code][start_date] except KeyError: try: tariffs_cache = gsp_group_cache["tariffs"] except KeyError: tariffs_cache = gsp_group_cache["tariffs"] = {} try: pc_cache = tariffs_cache[ds.pc_code] except KeyError: pc_cache = tariffs_cache[ds.pc_code] = {} try: tariffs = pc_cache[ds.llfc_code] except KeyError: tariffs = pc_cache[ds.llfc_code] = {} try: tariff = tariffs[start_date] except KeyError: tariff = None try: tariff_list = get_file_rates(ds.caches, ds.dno_code, start_date)[ ds.gsp_group_code ]["tariffs"] except KeyError as e: raise BadRequest(str(e)) for llfcs_pcs, tf in tariff_list.items(): key = llfcs_pcs.split("_") llfcs = [v.strip() for v in key[0].split(",")] if len(key) == 2: pcs = [v.strip() for v in key[1].split(",")] else: pcs = None if ds.llfc_code in llfcs and (pcs is None or ds.pc_code in pcs): tariff = tf break if tariff is None: raise BadRequest( f"For the DNO {ds.dno_code} and timestamp {hh_format(start_date)} " f"and GSP group {ds.gsp_group_code}, the LLFC {ds.llfc_code} " f"with PC {ds.pc_code} can't be found in the 'tariffs' section." ) tariffs[start_date] = tariff try: band = gsp_group_cache["bands"][start_date] except KeyError: try: bands_cache = gsp_group_cache["bands"] except KeyError: bands_cache = gsp_group_cache["bands"] = {} try: band = bands_cache[start_date] except KeyError: band = "green" ct_hr = hh["ct-decimal-hour"] weekend = hh["ct-day-of-week"] > 4 try: slots = get_file_rates(ds.caches, ds.dno_code, start_date)[ ds.gsp_group_code ]["bands"] except KeyError as e: raise BadRequest(str(e)) for slot in slots: slot_weekend = slot["weekend"] == 1 if slot_weekend == weekend and slot["start"] <= ct_hr < slot["finish"]: band = slot["band"] break bands_cache[start_date] = band try: laf = dno_cache["lafs"][ds.llfc_code][start_date] except KeyError: try: laf_cache = dno_cache["lafs"] except KeyError: laf_cache = dno_cache["lafs"] = {} try: laf_cache_llfc = laf_cache[ds.llfc_code] except KeyError: laf_cache_llfc = laf_cache[ds.llfc_code] = {} try: laf = laf_cache_llfc[start_date] except KeyError: dno_code = ds.dno_code if dno_code in ("88", "99"): laf_cache_llfc[start_date] = 1 else: for (laf,) in ds.sess.execute( select(Laf) .join(Llfc) .join(Party) .where( Party.dno_code == ds.dno_code, Llfc.code == ds.llfc_code, Laf.timestamp >= ds.start_date, Laf.timestamp <= ds.finish_date, ) ): laf_cache_llfc[laf.timestamp] = float(laf.value) try: laf = laf_cache_llfc[start_date] except KeyError: for cand in (hh["hist-start"], ds.forecast_date): laf_obj = ds.sess.execute( select(Laf) .join(Llfc) .join(Party) .where( Party.dno_code == ds.dno_code, Llfc.code == ds.llfc_code, Laf.timestamp == cand, ) ).scalar_one_or_none() if laf_obj is not None: laf_cache_llfc[start_date] = float(laf_obj.value) break try: laf = laf_cache_llfc[start_date] except KeyError: raise BadRequest( f"Missing LAF for DNO {ds.dno_code} and LLFC {ds.llfc_code} " f"and timestamps {hh_format(start_date)}, " f"{hh_format(hh['hist-start'])} and " f"{hh_format(ds.forecast_date)}" ) hh["laf"] = laf hh["gsp-kwh"] = laf * hh["msp-kwh"] hh["gsp-kw"] = hh["gsp-kwh"] * 2 kvarh = max( max(imp_msp_kvarh, exp_msp_kvarh) - (0.95 ** -2 - 1) ** 0.5 * hh["msp-kwh"], 0 ) hh["duos-reactive-kvarh"] = kvarh duos_reactive_rate = tariff["gbp-per-kvarh"] if duos_reactive_rate is not None: duos_reactive_rate = float(duos_reactive_rate) if duos_reactive_rate != 0: hh["duos-reactive-rate"] = duos_reactive_rate hh["duos-reactive-gbp"] = kvarh * duos_reactive_rate rate = float(tariff[KEYS[band]["tariff-rate"]]) hh[KEYS[band]["bill-rate"]] = rate hh[KEYS[band]["kwh"]] = hh["msp-kwh"] hh[KEYS[band]["gbp"]] = rate * hh["msp-kwh"] if hh["ct-decimal-hour"] == 23.5 and not ds.is_displaced: hh["duos-fixed-days"] = 1 rate = float(tariff["gbp-per-mpan-per-day"]) hh["duos-fixed-rate"] = rate hh["duos-fixed-gbp"] = rate hh["duos-availability-days"] = 1 kva = ds.sc hh["duos-availability-kva"] = kva rate = float(tariff["gbp-per-kva-per-day"]) hh["duos-availability-rate"] = rate hh["duos-availability-gbp"] = rate * kva if hh["ct-is-month-end"] and not ds.is_displaced: month_to = start_date month_from = to_utc(ct_datetime(hh["ct-year"], hh["ct-month"], 1)) md_kva = 0 days_in_month = 0 for dsc in ds.get_data_sources(month_from, month_to): for datum in dsc.hh_data: md_kva = max( md_kva, ( datum["msp-kw"] ** 2 + max(datum["imp-msp-kvar"], datum["exp-msp-kvar"]) ** 2 ) ** 0.5, ) if datum["ct-decimal-hour"] == 0: days_in_month += 1 excess_kva = max(md_kva - ds.sc, 0) if "excess-gbp-per-kva-per-day" in tariff and excess_kva != 0: rate = float(tariff["excess-gbp-per-kva-per-day"]) hh["duos-excess-availability-kva"] = excess_kva rate = float(tariff["excess-gbp-per-kva-per-day"]) hh["duos-excess-availability-rate"] = rate hh["duos-excess-availability-days"] = days_in_month hh["duos-excess-availability-gbp"] = rate * excess_kva * days_in_month
def vb(ds): to_exit_commodity_rate_set = ds.rate_sets["to_exit_commodity_rate"] so_exit_commodity_rate_set = ds.rate_sets["so_exit_commodity_rate"] dn_system_commodity_rate_set = ds.rate_sets["dn_system_commodity_rate"] dn_system_capacity_rate_set = ds.rate_sets["dn_system_capacity_rate"] dn_system_capacity_fixed_rate_set = ds.rate_sets[ "dn_system_capacity_fixed_rate"] dn_customer_capacity_rate_set = ds.rate_sets["dn_customer_capacity_rate"] dn_customer_capacity_fixed_rate_set = ds.rate_sets[ "dn_customer_capacity_fixed_rate"] dn_customer_fixed_rate_set = ds.rate_sets["dn_customer_fixed_rate"] dn_ecn_rate_set = ds.rate_sets["dn_ecn_rate"] dn_ecn_fixed_rate_set = ds.rate_sets["dn_ecn_fixed_rate"] for hh in ds.hh_data: soq = hh["soq"] aq = hh["aq"] nts_rates = get_file_rates(ds.caches, "g_nts_commodity", hh["start_date"]) to_exit_commodity_rate = float(nts_rates["to_exit_gbp_per_kwh"]) to_exit_commodity_rate_set.add(to_exit_commodity_rate) hh["to_exit_commodity_rate"] = to_exit_commodity_rate so_exit_commodity_rate = float(nts_rates["so_exit_gbp_per_kwh"]) so_exit_commodity_rate_set.add(so_exit_commodity_rate) hh["so_exit_commodity_rate"] = so_exit_commodity_rate rates = get_file_rates(ds.caches, "g_dn", hh["start_date"]) dn_rates = rates["gdn"][ds.g_dn_code] system_commodity_rates = dn_rates["system_commodity"] system_capacity_rates = dn_rates["system_capacity"] customer_capacity_rates = dn_rates["customer_capacity"] customer_fixed_rates = dn_rates["customer_fixed"] if aq <= 73200: pref = "to_73200_" dn_system_commodity_rate = float( system_commodity_rates[pref + "gbp_per_kwh"]) dn_system_capacity_rate = float( system_capacity_rates[pref + "gbp_per_kwh_per_day"]) dn_customer_capacity_rate = float( customer_capacity_rates[pref + "gbp_per_kwh_per_day"]) dn_customer_fixed_rate = 0 elif 73200 < aq < 732000: pref = "73200_to_732000_" dn_system_commodity_rate = float( system_commodity_rates[pref + "gbp_per_kwh"]) dn_system_capacity_rate = float( system_capacity_rates[pref + "gbp_per_kwh_per_day"]) dn_customer_capacity_rate = float( customer_capacity_rates[pref + "gbp_per_kwh_per_day"]) if ds.g_reading_frequency_code == "A": dn_customer_fixed_rate = float( customer_fixed_rates[pref + "biannual_gbp_per_day"]) else: dn_customer_fixed_rate = float( customer_fixed_rates[pref + "monthly_gbp_per_day"]) else: key = "732000_and_over" system_commodity_rts = system_commodity_rates[key] dn_system_commodity_rate = max( float(system_commodity_rts["minimum_gbp_per_kwh"]), float(system_commodity_rts["gbp_per_kwh"]) * soq**float(system_commodity_rts["exponent"]), ) system_capacity_rts = system_capacity_rates[key] dn_system_capacity_rate = max( float(system_capacity_rts["minimum_gbp_per_kwh_per_day"]), float(system_capacity_rts["gbp_per_kwh_per_day"]) * soq**float(system_capacity_rts["exponent"]), ) customer_capacity_rts = customer_capacity_rates[key] dn_customer_capacity_rate = float( customer_capacity_rts["gbp_per_kwh_per_day"]) * soq**float( customer_capacity_rts["exponent"]) dn_customer_fixed_rate = 0 dn_system_commodity_rate_set.add(dn_system_commodity_rate) hh["dn_system_commodity_rate"] = dn_system_commodity_rate dn_system_capacity_rate_set.add(dn_system_capacity_rate) hh["dn_system_capacity_rate"] = dn_system_capacity_rate dn_system_capacity_fixed_rate = soq * dn_system_capacity_rate dn_system_capacity_fixed_rate_set.add(dn_system_capacity_fixed_rate) hh["dn_system_capacity_fixed_rate"] = dn_system_capacity_fixed_rate dn_customer_capacity_rate_set.add(dn_customer_capacity_rate) hh["dn_customer_capacity_rate"] = dn_customer_capacity_rate dn_customer_capacity_fixed_rate = soq * dn_customer_capacity_rate dn_customer_capacity_fixed_rate_set.add( dn_customer_capacity_fixed_rate) hh["dn_customer_capacity_fixed_rate"] = dn_customer_capacity_fixed_rate dn_customer_fixed_rate_set.add(dn_customer_fixed_rate) hh["dn_customer_fixed_rate"] = dn_customer_fixed_rate dn_ecn_rate = float(rates["exit_zones"][ds.g_exit_zone_code] ["exit_capacity_gbp_per_kwh_per_day"]) dn_ecn_rate_set.add(dn_ecn_rate) hh["dn_ecn_rate"] = dn_ecn_rate dn_ecn_fixed_rate = dn_ecn_rate * soq dn_ecn_fixed_rate_set.add(dn_ecn_fixed_rate) hh["dn_ecn_fixed_rate"] = dn_ecn_fixed_rate