Skip to main content

Optimize load shifting based on known prices and a given flexibility level

Project description

load-shift-optimizer logo

Shift loads optimally to minimize electricity costs

Ruff Lint Unit Tests

Python License: MIT

loadshift helps you optimally shift loads based on known prices and a given flexibility level, where the flexibility level indicates how many hours earlier or later a load can run. The package can be used to determine optimal load shifts based on day-ahead electricity prices, or to evaluate potential savings from various load-shifting scenarios.

Features

  • Cost Optimization - Shift loads optimally to minimize costs based on known electricity prices.
  • 🎛️ Flexible Constraints - Define how many hours loads can shift earlier or later, transfer rate limits, and power capacity to match your use case.
  • 📅 Moving Horizon - Daily optimization approach that replicates real-world day-ahead market scenarios.

Example

The example below shows how electricity prices and residential loads change over a typical day: prices peak in the morning and evening, while residential loads peak in the evening when people get home. The two rightmost panels illustrate the results of shifting loads optimally for two flexibility levels: ±2 hours and ±4 hours. Observe how more and more consumption shifts towards nighttime and the afternoon as the flexibility level increases.

Installation

From PyPI (recommended)

To use load-shift-optimizer in your project, install it from PyPI:

pip install loadshift

By default, this installs the free open-source MIP solver (CBC backend). For better performance on large problems, you can install with Gurobi support if you have a Gurobi license:

pip install loadshift[gurobi]

From source (for examples and development)

If you want to explore the examples or contribute to the project, follow these steps to install from source:

# clone repository
$ git clone https://github.com/NoviaIntSysGroup/load-shift-optimizer.git
$ cd load-shift-optimizer

# install package and development dependencies (with MIP solver)
$ uv sync

# OR install with Gurobi support (requires a license)
$ uv sync --extra gurobi

Usage

Basic Optimization

import numpy as np
from loadshift import LoadShifter

# Define your price and demand data
price = np.array([30, 80, 20, 40, 35, 25])  # ct/kWh
demand = np.array([10, 15, 8, 12, 10, 9])   # kWh

# Create optimizer with flexibility constraints
optimizer = LoadShifter(
    max_demand_advance=2,      # Can shift loads up to 2 hours earlier
    max_demand_delay=3,        # Can shift loads up to 3 hours later
    max_hourly_purchase=20,    # Maximum 20 kWh per hour
    max_rate=10                # Maximum 10 kW transfer rate
)

# Optimize demand
result = optimizer.optimize_demand(price, demand)

print("Optimal demand:", result["optimal_demand"])
print("Demand shift:", result["optimal_shift"])

Moving Horizon Optimization

import pandas as pd
from loadshift import moving_horizon

# Create DataFrames with a datetime index
index = pd.date_range("2024-01-01", periods=72, freq="h")
price_data = pd.DataFrame({"price": price_values}, index=index)
demand_data = pd.DataFrame({"demand": demand_values}, index=index)

# Configuration
config = {
    "daily_decision_hour": 12,     # Make decisions at noon each day
    "n_lookahead_hours": 36,       # Look ahead 36 hours
    "load_shift": {
        "max_demand_advance": 2,
        "max_demand_delay": 3,
        "max_hourly_purchase": 20,
        "max_rate": 10
    }
}

# Run moving horizon optimization
result = moving_horizon(price_data, demand_data, config)

# Access optimized demand and shifts
optimized = result["results"]
print(optimized.head())

Development

Install development requirements and set up the hooks:

uv sync
uv run pre-commit install --hook-type pre-commit --hook-type pre-push

Before committing or pushing run:

uv run ruff check .
uv run pytest

Contributing

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run the test suite (uv run pytest)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

Please ensure your code follows our style guidelines:

  • Use Ruff for code formatting and linting
  • Follow Google's Python style guide for docstrings
  • Include type annotations for all functions
  • Add tests for new functionality

Acknowledgements

This tool was developed within the "Demand response - Promoting electricity demand response management in Ostrobothnia" project co-funded by the European Union through the "Just Transition Fund" under the "A Renewing and Skilled Finland 2021–2027" programme.

License

This project is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

loadshift-0.1.0.tar.gz (101.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

loadshift-0.1.0-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file loadshift-0.1.0.tar.gz.

File metadata

  • Download URL: loadshift-0.1.0.tar.gz
  • Upload date:
  • Size: 101.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.4

File hashes

Hashes for loadshift-0.1.0.tar.gz
Algorithm Hash digest
SHA256 61660b6d58b277510d5e04c86f4811c6ece95a39f2fac5201f6079d964e8acc1
MD5 64d8982ede0577aa42750d28e0c54a27
BLAKE2b-256 31391bbb27d96899f357e49412649dd10434d90fe4790b05f203de0ca0745758

See more details on using hashes here.

File details

Details for the file loadshift-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: loadshift-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.4

File hashes

Hashes for loadshift-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b22bcb416dc8c558725d0b0eb7428e2f9f171eab2f2790b78d2ec2f32a92867d
MD5 65792f741cafaa43f5811db979e7cfb8
BLAKE2b-256 07fe6a648efa127f61499db7ab749d00a2d8c7973626cf506e623792113909a0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page