Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
 def file_rate(self, contract_name, timestamp, rate_name):
     return get_file_rates(self.caches, contract_name, timestamp)[rate_name]
Esempio n. 9
0
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
        )
Esempio n. 10
0
 def get_file_rates(self, contract_name, timestamp):
     return get_file_rates(self.caches, contract_name, timestamp)
Esempio n. 11
0
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)
Esempio n. 12
0
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
Esempio n. 13
0
    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)
Esempio n. 14
0
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
Esempio n. 15
0
    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"]] = {}
Esempio n. 16
0
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
Esempio n. 17
0
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
Esempio n. 18
0
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))
Esempio n. 19
0
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
Esempio n. 20
0
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