Skip to content

Example usage - simple battery model#2

Merged
fletchapin merged 11 commits into
mainfrom
feature/battery-example
May 19, 2025
Merged

Example usage - simple battery model#2
fletchapin merged 11 commits into
mainfrom
feature/battery-example

Conversation

@arao53

@arao53 arao53 commented May 14, 2025

Copy link
Copy Markdown
Contributor

Changes

  • electric_emission_cost/costs.py: updated get_charge_df function to handle fixed charges.
  • electric_emission_cost/data/tariff.csv: included example tariff
  • examples/battery_model.py: include simple system model of an electric battery that is applied to a sinusoidal industrial load. The class is built in pyomo. Future versions should include a cvxpy example.
  • examples/example_pyomo_jupyter.ipynb: includes a Jupyter notebook that details the steps in obtaining charge arrays from the tariff and adding them to the pyomo battery model.

@arao53
arao53 requested review from Copilot and fletchapin May 14, 2025 21:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for handling fixed charges in the charge DataFrame, provides an example tariff CSV, and introduces a simple Pyomo-based battery model example.

  • Updated get_charge_df to optionally distribute or drop fixed charges.
  • Added an example tariff (tariff.csv) demonstrating typical time-of-use blocks.
  • Introduced examples/battery_model.py, a runnable Pyomo battery storage model example.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
examples/battery_model.py New example class for time-discretized Pyomo battery model
electric_emission_cost/data/tariff.csv Sample tariff data including fixed and time-of-use charges
electric_emission_cost/costs.py Enhanced get_charge_df to handle fixed charges and updated step count logic in cost calculation
Comments suppressed due to low confidence (4)

examples/battery_model.py:112

  • [nitpick] Consider renaming power_C and power_D to power_ch and power_dis (or lowercase snake_case) for consistency with other variable names.
model.power_C = Var(model.t, bounds=(0, self.powercapacity), initialize=0, doc="Charging power")

electric_emission_cost/data/tariff.csv:2

  • The tab (\t) between the two URLs may break CSV parsing; consider quoting the entire Notes field or splitting into separate columns.
electric,customer,,,,,,,,,,,666.65,666.65,$/month,https://www.pnm.com/...pdf/…\thttps://www.pnm.com/rates2

electric_emission_cost/costs.py:339

  • The variable datetime shadows the datetime module alias (dt); rename this DataFrame to e.g. datetime_df for clarity.
datetime = pd.DataFrame(

electric_emission_cost/costs.py:304

  • New keep_fixed_charges behavior should have unit tests covering both branches (True/False) and verifying charge distribution or removal.
def get_charge_df(start_dt, end_dt, rate_data, resolution="15m", keep_fixed_charges=False):

Comment thread examples/battery_model.py Outdated
Comment thread examples/battery_model.py
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

arao53 and others added 2 commits May 14, 2025 14:16
remove unnecessary imports and adding docs.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

@fletchapin fletchapin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor questions or changes, but overall looks good!

Comment thread electric_emission_cost/costs.py Outdated

def get_charge_df(start_dt, end_dt, rate_data, resolution="15m"):
def get_charge_df(
start_dt, end_dt, rate_data, resolution="15m", keep_fixed_charges=False

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the default behavior should be to keep the fixed charges (i.e., keep_fixed_charges =True not False) but otherwise this seems like a good feature. Is there a reason to go through the effort of dividing the fixed charge over the length of the array? Maybe it could be useful and I've just never computed them in that way

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense! I figured it was either that or assign it to time step 0 and make the rest of the time steps 0 value. Either way, we need an array of length T to build the data frame.

if model is None:
n_steps = consumption_data.shape[0]
else: # Pyomo does not support shape attribute
n_steps = len(consumption_data.extract_values())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did extract_values() throw an error or do you just think it is unnecessary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it did.

Comment thread examples/battery_model.py Outdated
This class models the behavior of a battery system operating on the site of an industrial power consumer.
It uses time-discretized simulation to optimize battery usage based on input parameters and baseline load data.

Parameters:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I usually add format the docstring like this to ensure they format correctly with Sphinx:

    Parameters
    -----------
    params (dict): A dictionary of model parameters. Expected keys include:
            - 'start_date' (str): The start date of the simulation in ISO format (e.g., 'YYYY-MM-DDTHH:MM:SS').
            - 'end_date' (str): The end date of the simulation in ISO format.
            - 'timestep' (float): The time step for the simulation in hours.
            (Additional keys may be required depending on the specific model configuration.)
    
    baseload (array-like): The baseline load profile for the site, provided as a time series.
    
    baseload_repeat (bool, optional): If True, the baseline load profile is repeated to match the simulation period.
            Defaults to False.

@we3lab we3lab deleted a comment from Copilot AI May 19, 2025
@arao53
arao53 requested a review from fletchapin May 19, 2025 22:08
@fletchapin
fletchapin merged commit 1da27c7 into main May 19, 2025
@fletchapin
fletchapin deleted the feature/battery-example branch June 11, 2025 20:32
avdudchenko added a commit to avdudchenko/eeco that referenced this pull request Jul 11, 2026
fletchapin added a commit that referenced this pull request Jul 24, 2026
* Update costs.py

* update index_set

* fix lint

* lint #2

* Update costs.py

* test fixes

* black

* remove gurobi and use scip

* Update setup.py

* Update setup.py

* change scip install

* update costs

* remove gurbi dept

* update test runs

* Update test_and_lint.yml

* Update test_and_lint.yml

* Update test_and_lint.yml

* Update test_and_lint.yml

* Update test_and_lint.yml

* black

* Update test_and_lint.yml

* Update test_and_lint.yml

* Update utils.py

* Added overwrite flag with warning to create_pyomo_model_index_ref

* Autoreformatted with black

* fixed util/emission tests

* missed check

* lint

* dumb lint

* Update costs.py

* names/bug

* blk

* add explicti indexed

* blk

* Updated model.t to model.dummy_t to check for edge cases implicitly relying on old model.t

* Switching docstrings to NumPy format (from Google)

* fix tests

* Update utils.py

* Resolvd flake8 errors

---------

Co-authored-by: Fletcher Chapin <fletchapin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants