Source code for openoa.utils.metadata_fetch

"""
This module fetches metadata of wind farms
"""

from __future__ import annotations

from typing import TYPE_CHECKING
from pathlib import Path

import eia
import numpy as np
import pandas as pd

from openoa.utils import unit_conversion


if TYPE_CHECKING:
    from openoa import PlantData


[docs] def fetch_eia( api_key: str, plant_id: str, file_path: str | Path, plant_file: str | Path, plant_sheet: str | Path, wind_file: str | Path, wind_sheet: str | Path, ): """ Read in EIA data of wind farm of interest: - from EIA API for monthly productions, return monthly net energy generation time series - from local Excel files for wind farm metadata, return dictionary of metadata Args: api_key(:obj:`str`): 32-character user-specific API key, obtained from EIA. plant_id(:obj:`str`): 5-character EIA power plant code. file_path(:obj:`str`): Directory with EIA metadata .xlsx files. plant_file(:obj:`str` | `Path`): Name of the plant metadata Excel file in :py:attr:`file_path`. Formerly hard-coded to: "2___Plant_Y2017.xlsx". plant_sheet(:obj:`str`): The name of the sheet containing the data in :py:attr:`plant_file`. Formerly hard-coded as "Plant". wind_file(:obj:`str` | `Path`): Name of the wind metadata Excel file in :py:attr:`file_path`. Formerly hard-coded to: ""3_2_Wind_Y2017.xlsx". wind_sheet(:obj:`str`): The name of the sheet containing the data in :py:attr:`plant_file`. Formerly hard-coded as "Operable". Returns: :obj:`pandas.Series`: monthly net energy generation in MWh :obj:`dictionary`: metadata of the wind farm with 'plant_id' """ file_path = Path(file_path).resolve() # EIA metadata plant_var_list = [ "City", "Latitude", "Longitude", "Balancing Authority Name", "Transmission or Distribution System Owner", ] wind_var_list = [ "Utility Name", "Plant Name", "State", "County", "Nameplate Capacity (MW)", "Operating Month", "Operating Year", "Number of Turbines", "Predominant Turbine Manufacturer", "Predominant Turbine Model Number", "Turbine Hub Height (Feet)", ] def meta_dic_fn(metafile: str | Path, sheet: str, var_list: list[str]): all_plant = pd.read_excel(file_path / metafile, sheet_name=sheet, skiprows=1) eia_plant = all_plant.loc[ all_plant["Plant Code"] == np.int64(plant_id) ] # specific wind farm if eia_plant.shape[0] == 0: # Couldn't locate EIA ID in database raise Exception("Plant ID not found in EIA database") eia_info = eia_plant[var_list] # select column eia_info = eia_info.reset_index(drop=True) # reset index to 0 eia_dic = eia_info.T.to_dict() # convert to dictionary out_dic = eia_dic[0] # remove extra level of dictionary, "0" in this case return out_dic # file path with 2017 EIA metadata files plant_dict = meta_dic_fn(plant_file, plant_sheet, plant_var_list) wind_dict = meta_dic_fn(wind_file, wind_sheet, wind_var_list) # convert feet to meter and delete reference to feet hub_height = np.round( unit_conversion.convert_feet_to_meter(wind_dict["Turbine Hub Height (Feet)"]) ) wind_dict.update({"Turbine Hub Height (m)": hub_height}) wind_dict.pop("Turbine Hub Height (Feet)", None) out_dic = plant_dict.copy() out_dic.update(wind_dict) # append dictionary # EIA monthly energy production data api = eia.API(api_key) # get data from EIA series_search_m = api.data_by_series(series="ELEC.PLANT.GEN.%s-ALL-ALL.M" % plant_id) eia_monthly = pd.DataFrame(series_search_m) # net monthly energy generation of wind farm in MWh eia_monthly.columns = ["eia_monthly_mwh"] # rename column eia_monthly = eia_monthly.set_index( pd.DatetimeIndex(eia_monthly.index) ) # convert to DatetimeIndex return eia_monthly, out_dic
[docs] def attach_eia_data( project: PlantData, api_key: str, plant_id: str, file_path: str | Path, plant_file: str | Path, plant_sheet: str | Path, wind_file: str | Path, wind_sheet: str | Path, ): """ Assign EIA meta data to PlantData object, which is by default an empty dictionary. Args: project(:obj:`PlantData`): PlantData object for a particular project api_key(:obj:`str`): 32-character user-specific API key, obtained from EIA. plant_id(:obj:`str`): 5-character EIA power plant code. file_path(:obj:`str`): Directory with EIA metadata .xlsx files. plant_file(:obj:`str` | `Path`): Name of the plant metadata Excel file in :py:attr:`file_path`. Formerly hard-coded to: "2___Plant_Y2017.xlsx". plant_sheet(:obj:`str`): The name of the sheet containing the data in :py:attr:`plant_file`. wind_file(:obj:`str` | `Path`): Name of the wind metadata Excel file in :py:attr:`file_path`. Formerly hard-coded to: ""3_2_Wind_Y2017.xlsx". wind_sheet(:obj:`str`): The name of the sheet containing the data in :py:attr:`plant_file`. Returns: (None) """ project.eia["api_key"] = api_key project.eia["data_dir"] = file_path project.eia["eia_id"] = plant_id project.eia["monthly_energy"], project.eia["meta_data"] = fetch_eia( api_key, plant_id, file_path, plant_file, plant_sheet, wind_file, wind_sheet )