Source code for fleetrl.utils.observation.observer_price_only

import numpy as np
import pandas as pd

from fleetrl.utils.observation.observer import Observer
from fleetrl.utils.load_calculation.load_calculation import LoadCalculation
from fleetrl.fleet_env.config.ev_config import EvConfig

[docs] class ObserverPriceOnly(Observer): """ Observer for a model that only takes into account the price, but disregards PV and building load. """
[docs] def get_obs(self, db: pd.DataFrame, price_lookahead: int, bl_pv_lookahead: int, time: pd.Timestamp, ev_conf: EvConfig, load_calc: LoadCalculation, aux: bool, target_soc: list) -> dict: """ - define the starting and ending time via lookahead, np.where returns the index in the dataframe - add lookahead + 2 here because of rounding issues with the resample function on square times (00:00) - get data of price and date from the specific indices - resample data to only include one value per hour (the others are duplicates) - only take into account the current value, and the specified hours of lookahead :param db: Database from env :param price_lookahead: Lookahead in hours for price :param bl_pv_lookahead: Lookahead in hours for PV and building :param time: Current time :param ev_conf: EV config data, used for battery capacity, etc. :param load_calc: Load calc module, used for grid connection, etc. :param aux: Flag to include extra information on the problem or not. Can help with training :param target_soc: List for the current target SOC of each car :return: Dict of lists with different parts of the observation """ # soc and time left always present in environment soc = db.loc[(db['date'] == time), 'SOC_on_return'].values hours_left = db.loc[(db['date'] == time), 'time_left'].values # variables to hold observation data price = pd.DataFrame() tariff = pd.DataFrame() # define the starting and ending time via lookahead, np.where returns the index in the dataframe price_start = np.where(db["date"] == time)[0][0] # add lookahead + 2 here because of rounding issues with the resample function on square times (00:00) price_end = np.where(db["date"] == (time + np.timedelta64(price_lookahead+2, 'h')))[0][0] # get data of price and date from the specific indices price["DELU"] = db["DELU"][price_start: price_end] price["date"] = db["date"][price_start: price_end] tariff["tariff"] = db["tariff"][price_start: price_end] tariff["date"] = db["date"][price_start: price_end] # resample data to only include one value per hour (the others are duplicates) price = price.resample("H", on="date").first()["DELU"].values tariff = tariff.resample("H", on="date").first()["tariff"].values # only take into account the current value, and the specified hours of lookahead price = np.multiply(np.add(price[0:price_lookahead+1], ev_conf.fixed_markup), ev_conf.variable_multiplier) tariff = np.multiply(tariff[0:price_lookahead+1], 1-ev_conf.feed_in_deduction) ### # Auxiliary observations that might make it easier for the agent # target soc there = db.loc[db["date"]==time, "There"].values target_soc = target_soc * there # maybe need to typecast to list charging_left = np.subtract(target_soc, soc) hours_needed = charging_left * load_calc.batt_cap / (load_calc.evse_max_power * ev_conf.charging_eff) laxity = np.subtract(hours_left / (np.add(hours_needed, 0.001)), 1) * there laxity = np.clip(laxity, 0, 5) # could also be a vector evse_power = load_calc.evse_max_power * np.ones(1) month_sin = np.sin(2 * np.pi * time.month/12) month_cos = np.cos(2 * np.pi * time.month/12) week_sin = np.sin(2 * np.pi * time.weekday() / 7) week_cos = np.cos(2 * np.pi * time.weekday() / 7) hour_sin = np.sin(2 * np.pi * time.hour / 24) hour_cos = np.cos(2 * np.pi * time.hour / 24) obs = { "soc": list(soc), # state of charge "hours_left": list(hours_left), # hours left at the charger "price": list(price), # price for charging "tariff": list(tariff), # price received when discharging "there": list(there), # boolean, is the car i there or not "target_soc": list(target_soc), # target soc of car i "charging_left": list(charging_left), # charging % left "hours_needed": list(hours_needed), # hours needed to get to target soc "laxity": list(laxity), # laxity factor "evse_power": list(evse_power), # evse power in kW "month_sin": month_sin, # month in sin, and so on "month_cos": month_cos, "week_sin": week_sin, "week_cos": week_cos, "hour_sin": hour_sin, "hour_cos": hour_cos } if aux: return obs else: return {key: obs[key] for key in ["soc", "hours_left", "price", "tariff"]}
[docs] @staticmethod def get_trip_len(db: pd.DataFrame, car: int, time: pd.Timestamp) -> float: """ :param db: from the env :param car: car ID :param time: current timestamp :return: length of trip in hours as a float """ trip_len = db.loc[(db["ID"] == car) & (db["date"] == time), "last_trip_total_length_hours"].values return trip_len