Spaces:
Sleeping
Sleeping
File size: 5,547 Bytes
e733d30 d58b6ea b1d06e1 d58b6ea e733d30 d58b6ea e733d30 b1d06e1 d58b6ea b1d06e1 e733d30 b1d06e1 e733d30 b1d06e1 e733d30 c5bd69c e733d30 fcbe190 e733d30 fcbe190 e733d30 fcbe190 e733d30 b1d06e1 e733d30 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
from dataclasses import dataclass
import numpy as np
import pandas as pd
from scipy.interpolate import interp1d
START = f"2021-01-01"
END = f"2022-01-01"
def read_datasets(met_filename, cons_filename, old_dataset=False):
# old_dataset mode is needed if we plug this into interpolate_and_join()
# rather than join_consumption_meteorology().
# Preprocessing meteorologic data
met_data = pd.read_csv(met_filename, compression='gzip', sep=';', skipinitialspace=True, na_values='n/a', skiprows=[0, 1, 2, 3, 4])
met_data['Time'] = met_data['Time'].astype(str)
date_time = met_data['Time'] = pd.to_datetime(met_data['Time'], format='%Y%m%d%H%M')
met_data = met_data.set_index('Time')
# Preprocessing consumption data
cons_data = pd.read_csv(cons_filename, sep='\t', skipinitialspace=True, na_values='n/a', decimal=',')
cons_data['Time'] = pd.to_datetime(cons_data['Korrigált időpont'], format='%m/%d/%y %H:%M')
cons_data = cons_data.set_index('Time')
cons_data['Consumption'] = cons_data['Hatásos teljesítmény [kW]']
if old_dataset:
# consumption data is at 14 29 44 59 minutes, we move it by 1 minute
# to sync it with production data:
cons_data.index = cons_data.index + pd.DateOffset(minutes=1)
met_2021_data = met_data[(met_data.index >= START) & (met_data.index < END)]
cons_2021_data = cons_data[(cons_data.index >= START) & (cons_data.index < END)]
return met_2021_data, cons_2021_data
else:
return met_data, cons_data
def interpolate(df, target_idx):
return (df # 1. start with your data
.reindex(target_idx) # 2. align to the desired timestamps
.interpolate(method="time") # 3. interpolate *within* the range
.ffill().bfill() # 4. forward- and backward-fill anything still missing
)
def join_consumption_meteorology(
met_data: pd.DataFrame,
cons_data: pd.DataFrame,
target_freq: str = "5min",
) -> pd.DataFrame:
interp_method = "time"
met = met_data[["Production", "sr", "r", "t", "fs"]]
cons = cons_data[["Consumption"]]
cons.index = cons.index + pd.DateOffset(minutes=1)
start = max(cons.index.min(), met.index.min())
end = min(cons.index.max(), met.index.max())
cons = cons.loc[start:end].copy()
met = met .loc[start:end].copy()
# there are dupes because of daylight savings time.
cons = cons[~cons.index.duplicated(keep="last")]
common_idx = pd.date_range(start, end, freq=target_freq)[:-2]
cons_interp = interpolate(cons, common_idx)
met_interp = interpolate(met, common_idx)
# stitch together
# joined = pd.concat([cons_interp["Consumption"], met_interp["Production"]], axis=1)
joined = pd.concat([cons_interp, met_interp], axis=1)
return joined
# BESS parameters are now in BatteryModel
@dataclass
class SolarParameters:
solar_cell_num: float = 1140 # units
solar_efficiency: float = 0.93 * 0.96 # [dimensionless]
panel_power_at_NOCT: float = 280 # [W]
# this is the SR (solar radiation) level where panel_power_at_NOCT is produced:
NOCT_irradiation: float = 800 # [W/m^2]
# mutates met_2021_data
def add_production_field(met_2021_data, parameters):
# sr has dimension W/m^2.
sr = met_2021_data['sr']
# TODO use something a bit more fancy nonlinear if we have the temperature anyway.
nop_total = sr * parameters.solar_cell_num * parameters.solar_efficiency * parameters.panel_power_at_NOCT / parameters.NOCT_irradiation / 1e3
nop_total = nop_total.clip(0)
met_2021_data['Production'] = nop_total
def interpolate_and_join(met_2021_data, cons_2021_data):
print("this is obsoleted by join_consumption_meteorology(), do not use")
applicable = 24*60*365 - 15 + 5
demand_f = interp1d(range(0, 365*24*60, 15), cons_2021_data['Consumption'])
#demand_f = interp1d(range(0, 6*24*60, 15), cons_2021_data['Consumption'])
demand_interp = demand_f(range(0, applicable, 5))
production_f = interp1d(range(0, 365*24*60, 10), met_2021_data['Production'])
#production_f = interp1d(range(0, 6*24*60, 10), met_2021_data['Production'])
production_interp = production_f(range(0, applicable, 5))
all_2021_datetimeindex = pd.date_range(start=START, end=END, freq='5min')[:len(production_interp)]
all_2021_data = pd.DataFrame({'Consumption': demand_interp, 'Production': production_interp})
all_2021_data = all_2021_data.set_index(all_2021_datetimeindex)
return all_2021_data
# TODO build a dataframe instead
def monthly_analysis(results):
consumptions = []
for month in range(1, 13):
start = f"2021-{month:02}-01"
end = f"2021-{month+1:02}-01"
if month == 12:
end = "2022-01-01"
results_in_month = results[(results.index >= start) & (results.index < end)]
total = results_in_month['Consumption'].sum()
network = results_in_month['consumption_from_network'].sum()
solar = results_in_month['consumption_from_solar'].sum()
bess = results_in_month['consumption_from_bess'].sum()
consumptions.append([network, solar, bess])
consumptions = np.array(consumptions)
step_in_minutes = results.index.freq.n
# consumption is given in kW. each tick is step_in_minutes long (5mins, in fact)
# we get consumption in kWh if we multiply sum by step_in_minutes/60
consumptions_in_mwh = consumptions * (step_in_minutes / 60) / 1000
return consumptions_in_mwh
|