Git Product home page Git Product logo

hamlet's Introduction

HAMLET

Hierarchical Agent-based Markets for Local Energy Trading

An open-source tool for the agent-based development and testing of energy market applications (at a local level).

Description

Due to the increasing complexity of energy systems, the need for more detailed and realistic models has arisen. Agent-based models are a promising approach to model the behavior of individual actors in energy systems. For this purpose, we developed HAMLET, a modular and extendable open-source toolbox for the development and testing of market designs with a focus on local interactions at the distribution level. HAMLET is designed to be used by researchers to investigate the interactions between market participants and the impact of different market designs on the technical and economic performance of energy systems.

HAMLET was developed with extendability and modularity in mind. Therefore, each functionality can be easily swapped for another to test, for example, other market clearing algorithms, trading strategies, or control strategies. The aim of the tool is to provide a common platform for researchers to develop and test their own market designs and to compare their results with other market designs.

A documentation is currently being developed and will be available soon.

HAMLET was developed and is maintained by the Chair of Renewable and Sustainable Energy Systems of the Technical University of Munich. Version 0.1 (February 2024) was developed as part of the research project STROM, funded by the Bavarian Ministry of Economic Affairs, Regional Development and Energy.

Features

HAMLET offers...

  • a fully open-source, agent-based energy market modelling toolbox
  • a modular and extendable design for easy adaptation to your own research questions
  • integrated time-series data for several plant types (household loads, pv, wind, heat pumps, electric vehicles etc...)
  • template functionality for load and generation forecasting, trading strategies, market clearing algorithms and control strategies and much more...

so you only need to adapt the components you want to investigate and/or improve on

Installation

HAMLET is completely based on Python to keep the installation process simple. This installation guide will explain how to get HAMLET to run using PyCharm, Gurobi and Anaconda as example. However, other IDEs and package managers are perfectly suitable as well.

Install the following software:

- IDE: e.g. PyCharm
- Package Manager: e.g. Anaconda
- Solver: e.g. Gurobi* or CPLEX. GLPK can be used although this is non-ideal.

*Installation explained later in this README

Clone repository

You can download or clone the repository to a local directory of your choice. You can use version control tools such as GitHub Desktop, Sourcetree, GitKraken or pure Git. The link for pure Git is:

git clone https://github.com/tum-ewk/hamlet.git

If using PyCharm, clone the repository, for example, to ./PyCharmProjects/hamlet/

Create a virtual python environment

- Open the AnacondaPrompt.
- Type `conda env create -f ./PycharmProjects/hamlet/env.yml`
- Take care to set the correct (absolute) path to your cloned repository.

Activate the environment

- Open PyCharm
- Go to 'File->Open'
- Navigate to PyCharmProjects and open hamlet
- When the project has opened, go to 
     `File->Settings->Project->Python Interpreter->Show all->Add->Conda Environment
      ->Existing environment->Select folder->OK`

Install a solver (we recommend Gurobi)

- Go to gurobi.com
- Create an account with your university email 
- When the account has been activated, log in and download the newest Gurobi solver.
- Go to Academia->Academic Program and Licenses
- Follow the installation instructions under "Individual Academic Licenses" to activate your copy of Gurobi

Test your installation

- Navigate to ./PycharmProjects/hamlet/01 - examples
- Execute 01_create_scenario.py, followed by 02_execute_scenario.py
- When the simulation has completed (this may take some time, depending on your system), 
  analyze the results by executing 03_analyze_scenario.py (no analysis available yet)
- Look at the output plots under hamlet/05_results/example_singlemarket/analysis/ (once implemented)

Contact

Feel free to contact us if you want to contribute to this project, cooperate on an interesting research question or just to ask about the project.

Markus Doepfert
[email protected]
Research Associate @ TUM ENS

License

Copyright (C) 2023 TUM-ENS

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

hamlet's People

Contributors

jiahechu avatar rahulbattoo9 avatar tum-doepfert avatar

Stargazers

 avatar

Watchers

 avatar

hamlet's Issues

Hard coded parts in __adjust_weather_data_for_wind

Based on #1

Timezone is not computed based on config_general time info but hard-coded (see code snippet below). Change so that it uses config_general instead.

weather.index = dtime.tz_convert("Europe/Berlin")

Implementation of aggregator

Additional information

Currently, the aggregator is included in the config file but not yet implemented. For the implementation it needs to be checked how the config needs to look like to actually implement it, it needs to be considered in the scenario creation and execution. And of course the analysis once this exists.

Create forecasts for agent

Currently the forecaster class inits the forecaster to train all methods. However, it does so only for the plants and not the markets. This needs to be added.

Furthermore, the class requires a function that creates all the forecasts for each plant and market. I have added it to the class with some comments but feel free to change it however you like. I also added more variable to the init. Just let me know if you don't need some of them.


def make_forecasts(self):
    """Make forecasts for all plants."""
    # TODO: @Jiahe, please implement this method

    # Loop through all forecast columns (probably best to sort this by plant ID and market type)

    # Check if the model needs to be re-fitted

    # Make the forecast

    # Return the forecasts dataframe (i.e. self.forecasts)
    return self.forecasts

Adjust hierarchical coupling method in tasklist

Currently the task list contains the type of coupling, e.g. above_l. This needs to be replaced with just above when it is appropriate and in other instances with None. This way the market knows when coupling is necessary and when not without having to check it for itself. It only retrieves the other bids and offers if the row of the coupling column contains some other than None.

Task: Implementation of multiprocessing

Currently, the tool uses concurrent.futures thread-functionality to run processes in parallel. However, this does not speed up the process as the GIL hinders the processes to actually be executed in parallel. Therefore another approach needs to be used.

Database returns incorrect agent format

Bug in:
setup.py: __execute_agents_parallel() and __execute_agents()

Line where bug is found:

        # Get the data of the agents that are part of the tasklist
        agents = self.database.get_agent_data(region=tasklist[0, 'region'])

Issue
The following line returns a dict with the keys being the agent IDs. The dict should contain as keys the agent types and as subkeys the agent IDs.

Task: Implement chp plant

Implement chp. Lemlab's implementation can be used for inspiration.

This is lemlab's config setup for chp:

"chp_fraction": 0                         # fraction of prosumers with chp

 "chp_sizing_power": 1                     # thermal sizing of chp plant
                                           # 1 = thermal power of chp equals ceiled max heat demand
                                           # note: if value <1 without other heating devices, the simulation will crash

 "chp_heat_elec_ratio": 2                  # ratio of heating to electric power (p_th/p_el)

 "chp_efficiency": 0.9                     # efficiency of chp plant: (e_th + e_el)/e_tot

 "chp_capacity": [2, 3]                    # storage capacity in hours of chp power
                                           # note: value randomly chosen from list

 "chp_soc_init": 0                         # initial soc of the storage (0-1)

 "chp_tes_efficiency": 0.98                # charging and discharging efficiency of thermal energy storage

 "chp_fcast": "perfect"                    # heating demand forecasting technique
                                           #   "perfect" - perfect forecast of heating demand
                                           #   "nn" - neural network based on the included weather data
                                           #   "mr" - multiple regression based on the included weather data

 "chp_fcast_retraining_period": 86400      # models should be periodically retrained based on new data
                                           # how many seconds between retraining periods?

 "chp_fcast_update_period": 3600           # forecasts are periodically updated and saved to file where the
                                           # most current forecast can be retrieved by model predictive controllers
                                           # and market agents. How many seconds between updates?

Empty progress bar from creator appears when running the executor

When running the Executor, following progress bars appears:
Screenshot (9)
But actually there should be only one progress bar. If I delete from hamlet.creator.setup import Creator in HAMLET\hamlet\__init__.py, I got the right version of the progress bar:
Screenshot (11)
My assumption is that it's because the progress bar in class Creator is initialized outside of the __init__() function of the Creator:
Screenshot (12)
But if I move progress_bar = tqdm() into the def __init__() as self.progress_bar = tqdm(), I got the following error while creating the scenario:
Screenshot (13)

Fix bug when input format from pandapower is incorrect

If the input format of the demand/generation in the pandapower Excel file is too long, it cannot be casted as integer. Correct the line for all agent types and devices. The line looks most often like this:
old:
self.df[f"{key}/sizing/power_{num}"] = (self.df.index.map(df['power']) * 1e6).astype('Int64')

new (add round()):
self.df[f"{key}/sizing/power_{num}"] = (self.df.index.map(round(df['demand'] * 1e6))).astype('Int64')

Change fcast config for agents

Each forecast method for each device gets its own entry in the config file.

Change the creator so that it can work with the new feature.

Example:

    fcast: 
      method: naive_average                     # household load forecasting method
                                                # options:
                                                #   - perfect:       perfect knowledge of the future
                                                #   - naive:         today will be the same as yesterday
                                                #   - naive_average: today will be the same as the average the last n days
                                                #                    defined in naive_average_days
                                                #   - smoothed:      prediction value is a moving mean of the future values 
                                                #                    with the window width defined in smoothed_timesteps
                                                #   - sarma:         full sarma model with the order defined in sarma_order

      perfect:

      naive:


      naive_average:
        days: 2

      smoothed:
        timesteps: 9

      sarma:
        order: [2, 0, 2, 2, 0, 0, 96, 2, 0, 0, 672]
                                                # order of double seasonal arma model 
                                                # order: [s2_ar, 0, s2_ma, s2]

Error while creating grids in Creator

I got the following error when creating the single market scenario:
Screenshot 2023-08-15 at 00 44 07

I opened the debugger to figure out how to fix the error. I noticed at line 507 in setup.py (where the error occurs) self.grids is an empty dict. Then I went to lines 488-502 in setup.py, the following code defines self.grids:
Screenshot 2023-08-15 at 00 38 53

Here, path_grids is defined as 'HAMLET/04 - scenarios/example_single_market/grids'. But this folder doesn't exist at all. So at line 495, when using os.walk(path_grids) to define self.grids, we will get an empty dict for self.grids because nothing was looped through.

Let me know if this error while creating grids also occurs on your laptop or if I misunderstood something.

Create PV and Wind timeseries from json file

Include the functionality to create the generation time series for PV and wind using the spec json files. The function to be used are labeled with @jiahe and are found in creator/agents/agents.py class Agents.

Add methods to obtain general, weather and market to database class.

The database should contain methods that allow to obtain the entire general info, the weather as well as the market dict from the respective region (see #23 for the structure). The entire general info can then also be used to obtain the weather data as it is a subdict.

def get_general_data() -> dict:
    # code
    return data
    
def get_weather_data() -> dict:
    # code
    return data

def get_market_data(region: str) -> dict:
    # code
    return data

Create HP timeseries from json file

Include the creation of a cop and/or power timeseries based on the specifications json file. The function should return a pandas dataframe with the index as unix timestamp and the columns named after what they contain, e.g. 'cop'.

The function is in the Agents class named '__timeseries_from_specs_hp'.

All auxiliary functions should also be included in this class.

Untangling of classes

Create separate files for the subclasses of grids, agents and markets in the creator.

Error in the executor

Agents with only inflexible load will get in the executor this error message in the executor : (hope this is not only for me the case)
File "C:\Users\claud\PycharmProjects\HAMLET-develop\hamlet\executor\utilities\database\database.py", line 195, in get_bids_offers
bids_offers_table = self.filter_market_data(market=bids_offers_table, by=by, values=values, inclusive=True)
File "C:\Users\claud\PycharmProjects\HAMLET-develop\hamlet\executor\utilities\database\database.py", line 288, in filter_market_data
dtype = datetime_index.dtypes[0]
File "C:\Users\claud\anaconda3\envs\hamlet\lib\site-packages\polars\lazyframe\frame.py", line 672, in dtypes
return self._ldf.dtypes()
exceptions.ColumnNotFoundError: timestep

Bug: Fees and levies are calculated incorrectly

They are only applied to the current timestamp settlement but previous market clearings for the same timestep need to be also considered and feed and levies only applied to the net energy amount.

Database object are not inspectable

Bug in:
setup.py: __execute_agents_parallel() and __execute_agents()

Line where bug is found:

    # Get the data of the agents that are part of the tasklist
    agents = self.database.get_agent_data(region=tasklist[0, 'region'])

Issue
The following line returns a dict with AgentDB objects. However, I cannot inspect the objects and see what information they contain. When calling something like agents['sfh']['B0gUAuzRUlrkye1'] I would expect to see a dict of dicts instead of <hamlet.executor.utilities.database.agent_db.AgentDB object at 0x000002A4C0241300>

Bug in Creator: time series files are always the same if a agent has multiple plants of the same type when creating a scenario from grid

Checks

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of HAMLET.

Reproducible example

import sys
sys.path.append("..")  # Add the parent directory to the Python path for execution outside of an IDE
sys.path.append("./")  # Add the current directory to the Python path for execution in VSCode
from hamlet import Creator
from hamlet import functions as f
import os

# Path to the scenario folder (relative or absolute)
path = "../02_config/scenario_pv_60_hp_60_ev_60_transition"

# Create the creator object
sim = Creator(path=path)

# Create the scenario
sim.new_scenario_from_grids()

# get all agents in this scenario
sfh_agents = f.get_all_subdirectories("../04_scenarios/scenario_pv_60_hp_60_ev_60_transition/agents/sfh")

# now find the agent at grid bus 20136, since it has 3 EVs with different time series files according to electricity.xlsx
for sfh_agent in sfh_agents:    # iterate each agent to find agent at bus 20136, it has multiple EVs
    agent_path = os.path.join("../04_scenarios/scenario_pv_60_hp_60_ev_60_transition/agents/sfh", sfh_agent)
    agent_config = f.load_file(os.path.join(agent_path, "account.json"))    # load agent config to get the agent's bus

    if agent_config['general']['bus'] == 20136:     # find agent at bus 20136, print config for EVs of this agent
        print("Agent at bus 20136 has agent id " + sfh_agent + ", it has multiple EVs: \n")

        agent_plants = f.load_file(os.path.join(agent_path, "plants.json"))     # load plants config for this agent

        for plant in agent_plants.values():     # loop plants of this agent to find EVs
            if plant['type'] == 'ev':
                print(plant)

        break

Issue description

If an agent has multiple plants of the same type (e.g. EV), the time series files for all these EV plants are always the same as the first plant when creating a scenario from grid, even though they have different time series files according to the grid file (electricity.xlsx).

Expected behavior

The time series files should be individual for each plant as defined in the grid file (electricity.xlsx).

Screenshots

No response

Additional information

No response

Meters does not show the power consumption of the Heat Pump

Checks

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of HAMLET.

Reproducible example

Issue description

Meters doesnt show the power consumption of the Heat Pump. The Meters.ft file which is one of the Results form the Executor doesnt provide the power consumption of the heat pump

Expected behavior

Meters show the power consumption of the Heat Pump.

Screenshots

No response

Additional information

No response

All plants are made controllable in the Creator

Checks

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of HAMLET.

Reproducible example

# Make all plants controllable
self.df[f"{key}/sizing/controllable_{num}"] = True

Issue description

All plants are made controllable in the Creator in function def _pv_grid at the sfh file

Expected behavior

Not All plants are made controllable in the Creator

Screenshots

No response

Additional information

No response

Take out / Edit agent parameters

Some of the parameters only add unnecessary complexity which are not required in a simulation environment. Therefore, the functionality is not needed and the parameters should be taken out.

The parameters to take out are:

  • has_submeter
  • market_agent/preference_quality
  • market_agent/premium_preference_quality
  • meter (all subparameters)

Set all tables to respective dtype

The tables that are defined in the scenario creator still need to be assigned their dtype as currently they are still floats and objects while they can easily be turned into ints.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.