Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
gieljnssns authored Jan 29, 2024
2 parents a5a3361 + d9f6bfb commit 6bc4df4
Show file tree
Hide file tree
Showing 42 changed files with 1,848 additions and 438 deletions.
1 change: 1 addition & 0 deletions .devcontainer/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ main() {
pip install netCDF4

pip install -r requirements_webserver.txt
pip install requests-mock

rm -rf "$0"
}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
PYTHON: ${{ matrix.python-version }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand Down
46 changes: 46 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "EMHASS run",
"type": "python",
"request": "launch",
"program": "web_server.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}/src/emhass/",
"purpose":["debug-in-terminal"],
"justMyCode": true,
"env": {
"CONFIG_PATH": "/workspaces/emhass/config_emhass.yaml",
"OPTIONS_PATH": "/workspaces/emhass/options.json",
"SECRETS_PATH": "/workspaces/emhass/secrets_emhass.yaml",
"DATA_PATH": "/workspaces/emhass/data/",
}
},
{
"name": "EMHASS run ADDON",
"type": "python",
"request": "launch",
"program": "web_server.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}/src/emhass/",
"args": ["--addon", "true", "--url", "http://IPHERE:PORT/", "--key", "PLACEKEYHERE" ],
"purpose":["debug-in-terminal"],
"justMyCode": true,
"env": {
"CONFIG_PATH": "/workspaces/emhass/config_emhass.yaml",
"OPTIONS_PATH": "/workspaces/emhass/options.json",
"SECRETS_PATH": "/workspaces/emhass/secrets_emhass.yaml",
"DATA_PATH": "/workspaces/emhass/data/",
},

}
]
}
21 changes: 21 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "EMHASS install",
"command": "sudo",
"group": {
"kind": "build",
"isDefault": true
},
"args": [
"python3", "setup.py", "install"
],
"presentation": {
"echo": true,
"panel": "shared",
"focus": true
}
}
]
}
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## [0.7.0] - 2024-01-28
### Improvement
- Added a new feature to provide operating time windows for deferrable loads. Thanks to @michaelpiron
- Added lots of new options to be configured by the user. Thanks to @GeoDerp
- Updated stylesheet with mobile & dark theme by @GeoDerp
- Improved launch.json to fully test EMHASS on different configurations. Thanks to @GeoDerp
- Added new script to debug and develop new time series clustering feature
- Improved documentation. Thanks to @g1za
### Fix
- Updated github workflow actions/checkout to v4 and actions/setup-python to v5
- Changed default values for weight_battery_discharge and weight_battery_charge to zero
- Renamed classes to conform to PEP8
- Bump markupsafe from 2.1.3 to 2.1.4

## [0.6.2] - 2024-01-04
### Improvement
- Added option to pass additional weight for battery usage
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ COPY src/emhass/utils.py /app/src/emhass/utils.py
COPY src/emhass/web_server.py /app/src/emhass/web_server.py
COPY src/emhass/templates/index.html /app/src/emhass/templates/index.html
COPY src/emhass/static/style.css /app/src/emhass/static/style.css
COPY src/emhass/static/img/emhass_logo_short.svg /app/src/emhass/static/img/emhass_logo_short.svg
COPY src/emhass/static/img/emhass_icon.png /app/src/emhass/static/img/emhass_icon.png
COPY data/opt_res_latest.csv /app/data/opt_res_latest.csv

RUN python3 setup.py install
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@ Here is the list of the other additional dictionary keys that can be passed at r

- `def_total_hours` for the total number of hours that each deferrable load should operate.

- `def_start_timestep` for the timestep as from which each deferrable load is allowed to operate (if you don't want the deferrable load to use the whole optimization timewindow).

- `def_end_timestep` for the timestep before which each deferrable load should operate (if you don't want the deferrable load to use the whole optimization timewindow).

- `treat_def_as_semi_cont` to define if we should treat each deferrable load as a semi-continuous variable.

- `set_def_constant` to define if we should set each deferrable load as a constant fixed value variable with just one startup for each optimization task.
Expand Down Expand Up @@ -403,10 +407,14 @@ When applying this controller, the following `runtimeparams` should be defined:

- `def_total_hours` for the list of deferrable loads functioning hours. These values can decrease as the day advances to take into account receding horizon daily energy objectives for each deferrable load.

- `def_start_timestep` for the timestep as from which each deferrable load is allowed to operate (if you don't want the deferrable load to use the whole optimization timewindow). If you specify a value of 0 (or negative), the deferrable load will be optimized as from the beginning of the complete prediction horizon window.

- `def_end_timestep` for the timestep before which each deferrable load should operate (if you don't want the deferrable load to use the whole optimization timewindow). If you specify a value of 0 (or negative), the deferrable load optimization window will extend up to the end of the prediction horizon window.

A correct call for a MPC optimization should look like:

```
curl -i -H 'Content-Type:application/json' -X POST -d '{"pv_power_forecast":[0, 70, 141.22, 246.18, 513.5, 753.27, 1049.89, 1797.93, 1697.3, 3078.93], "prediction_horizon":10, "soc_init":0.5,"soc_final":0.6,"def_total_hours":[1,3]}' http://localhost:5000/action/naive-mpc-optim
curl -i -H 'Content-Type:application/json' -X POST -d '{"pv_power_forecast":[0, 70, 141.22, 246.18, 513.5, 753.27, 1049.89, 1797.93, 1697.3, 3078.93], "prediction_horizon":10, "soc_init":0.5,"soc_final":0.6,"def_total_hours":[1,3],"def_start_timestep":[0,3],"def_end_timestep":[0,6],}' http://localhost:5000/action/naive-mpc-optim
```

## A machine learning forecaster
Expand Down
150 changes: 78 additions & 72 deletions config_emhass.yaml
Original file line number Diff line number Diff line change
@@ -1,79 +1,85 @@
# Configuration file for EMHASS

retrieve_hass_conf:
- freq: 30 # The time step to resample retrieved data from hass in minutes
- days_to_retrieve: 8 # We will retrieve data from now and up to days_to_retrieve days
- var_PV: 'sensor.power_photovoltaics' # Photovoltaic produced power sensor in Watts
- var_load: 'sensor.power_load_no_var_loads' # Household power consumption sensor in Watts (deferrable loads should be substracted)
- load_negative: False # Set to True if the retrived load variable is negative by convention
- set_zero_min: True # A special treatment for a minimum value saturation to zero. Values below zero are replaced by nans
- var_replace_zero: # A list of retrived variables that we would want to replace nans with zeros
- 'sensor.power_photovoltaics'
- var_interp: # A list of retrived variables that we would want to interpolate nan values using linear interpolation
- 'sensor.power_photovoltaics'
- 'sensor.power_load_no_var_loads'
- method_ts_round: 'nearest' # Set the method for timestamp rounding, options are: first, last and nearest
freq: 30 # The time step to resample retrieved data from hass in minutes
days_to_retrieve: 8 # We will retrieve data from now and up to days_to_retrieve days
var_PV: 'sensor.power_photovoltaics' # Photovoltaic produced power sensor in Watts
var_load: 'sensor.power_load_no_var_loads' # Household power consumption sensor in Watts (deferrable loads should be substracted)
load_negative: False # Set to True if the retrived load variable is negative by convention
set_zero_min: True # A special treatment for a minimum value saturation to zero. Values below zero are replaced by nans
var_replace_zero: # A list of retrived variables that we would want to replace nans with zeros
- 'sensor.power_photovoltaics'
var_interp: # A list of retrived variables that we would want to interpolate nan values using linear interpolation
- 'sensor.power_photovoltaics'
- 'sensor.power_load_no_var_loads'
method_ts_round: 'nearest' # Set the method for timestamp rounding, options are: first, last and nearest

optim_conf:
- set_use_battery: False # consider a battery storage
- delta_forecast: 1 # days
- num_def_loads: 2
- P_deferrable_nom: # Watts
- 3000.0
- 750.0
- def_total_hours: # hours
- 5
- 8
- treat_def_as_semi_cont: # treat this variable as semi continuous
- True
- True
- set_def_constant: # set as a constant fixed value variable with just one startup for each 24h
- False
- False
- weather_forecast_method: 'scrapper' # options are 'scrapper' and 'csv'
- load_forecast_method: 'naive' # options are 'csv' to load a custom load forecast from a CSV file or 'naive' for a persistance model
- load_cost_forecast_method: 'hp_hc_periods' # options are 'hp_hc_periods' for peak and non-peak hours contracts and 'csv' to load custom cost from CSV file
- list_hp_periods: # list of different tariff periods (only needed if load_cost_forecast_method='hp_hc_periods')
- period_hp_1:
- start: '02:54'
- end: '15:24'
- period_hp_2:
- start: '17:24'
- end: '20:24'
- load_cost_hp: 0.1907 # peak hours load cost in €/kWh (only needed if load_cost_forecast_method='hp_hc_periods')
- load_cost_hc: 0.1419 # non-peak hours load cost in €/kWh (only needed if load_cost_forecast_method='hp_hc_periods')
- prod_price_forecast_method: 'constant' # options are 'constant' for constant fixed value or 'csv' to load custom price forecast from a CSV file
- prod_sell_price: 0.065 # power production selling price in €/kWh (only needed if prod_price_forecast_method='constant')
- set_total_pv_sell: False # consider that all PV power is injected to the grid (self-consumption with total sell)
- lp_solver: 'default' # set the name of the linear programming solver that will be used
- lp_solver_path: 'empty' # set the path to the LP solver
- set_nocharge_from_grid: False # avoid battery charging from the grid
- set_nodischarge_to_grid: True # avoid battery discharging to the grid
- set_battery_dynamic: False # add a constraint to limit the dynamic of the battery power in power per time unit
- battery_dynamic_max: 0.9 # maximum dynamic positive power variation in percentage of battery maximum power
- battery_dynamic_min: -0.9 # minimum dynamic negative power variation in percentage of battery maximum power
- weight_battery_discharge: 1.0 # weight applied in cost function to battery usage for discharge
- weight_battery_charge: 1.0 # weight applied in cost function to battery usage for charge
set_use_battery: False # consider a battery storage
delta_forecast: 1 # days
num_def_loads: 2
P_deferrable_nom: # Watts
- 3000.0
- 750.0
def_total_hours: # hours
- 5
- 8
def_start_timestep: # timesteps
- 0
- 0
def_end_timestep: # timesteps
- 0
- 0
treat_def_as_semi_cont: # treat this variable as semi continuous
- True
- True
set_def_constant: # set as a constant fixed value variable with just one startup for each 24h
- False
- False
weather_forecast_method: 'scrapper' # options are 'scrapper', 'csv', 'list', 'solcast' and 'solar.forecast'
load_forecast_method: 'naive' # options are 'csv' to load a custom load forecast from a CSV file or 'naive' for a persistance model
load_cost_forecast_method: 'hp_hc_periods' # options are 'hp_hc_periods' for peak and non-peak hours contracts and 'csv' to load custom cost from CSV file
list_hp_periods: # list of different tariff periods (only needed if load_cost_forecast_method='hp_hc_periods')
- period_hp_1:
- start: '02:54'
- end: '15:24'
- period_hp_2:
- start: '17:24'
- end: '20:24'
load_cost_hp: 0.1907 # peak hours load cost in €/kWh (only needed if load_cost_forecast_method='hp_hc_periods')
load_cost_hc: 0.1419 # non-peak hours load cost in €/kWh (only needed if load_cost_forecast_method='hp_hc_periods')
prod_price_forecast_method: 'constant' # options are 'constant' for constant fixed value or 'csv' to load custom price forecast from a CSV file
prod_sell_price: 0.065 # power production selling price in €/kWh (only needed if prod_price_forecast_method='constant')
set_total_pv_sell: False # consider that all PV power is injected to the grid (self-consumption with total sell)
lp_solver: 'default' # set the name of the linear programming solver that will be used
lp_solver_path: 'empty' # set the path to the LP solver
set_nocharge_from_grid: False # avoid battery charging from the grid
set_nodischarge_to_grid: True # avoid battery discharging to the grid
set_battery_dynamic: False # add a constraint to limit the dynamic of the battery power in power per time unit
battery_dynamic_max: 0.9 # maximum dynamic positive power variation in percentage of battery maximum power
battery_dynamic_min: -0.9 # minimum dynamic negative power variation in percentage of battery maximum power
weight_battery_discharge: 0.0 # weight applied in cost function to battery usage for discharge
weight_battery_charge: 0.0 # weight applied in cost function to battery usage for charge

plant_conf:
- P_grid_max: 9000 # The maximum power that can be supplied by the utility grid in Watts
- module_model: # The PV module model
- 'CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M'
- inverter_model: # The PV inverter model
- 'Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_'
- surface_tilt: # The tilt angle of your solar panels
- 30
- surface_azimuth: # The azimuth angle of your PV installation
- 205
- modules_per_string: # The number of modules per string
- 16
- strings_per_inverter: # The number of used strings per inverter
- 1
- Pd_max: 1000 # If your system has a battery (set_use_battery=True), the maximum discharge power in Watts
- Pc_max: 1000 # If your system has a battery (set_use_battery=True), the maximum charge power in Watts
- eta_disch: 0.95 # If your system has a battery (set_use_battery=True), the discharge efficiency
- eta_ch: 0.95 # If your system has a battery (set_use_battery=True), the charge efficiency
- Enom: 5000 # If your system has a battery (set_use_battery=True), the total capacity of the battery stack in Wh
- SOCmin: 0.3 # If your system has a battery (set_use_battery=True), the minimun allowable battery state of charge
- SOCmax: 0.9 # If your system has a battery (set_use_battery=True), the minimun allowable battery state of charge
- SOCtarget: 0.6 # If your system has a battery (set_use_battery=True), the desired battery state of charge at the end of each optimization cycle
P_grid_max: 9000 # The maximum power that can be supplied by the utility grid in Watts
module_model: # The PV module model
- 'CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M'
inverter_model: # The PV inverter model
- 'Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_'
surface_tilt: # The tilt angle of your solar panels
- 30
surface_azimuth: # The azimuth angle of your PV installation
- 205
modules_per_string: # The number of modules per string
- 16
strings_per_inverter: # The number of used strings per inverter
- 1
Pd_max: 1000 # If your system has a battery (set_use_battery=True), the maximum discharge power in Watts
Pc_max: 1000 # If your system has a battery (set_use_battery=True), the maximum charge power in Watts
eta_disch: 0.95 # If your system has a battery (set_use_battery=True), the discharge efficiency
eta_ch: 0.95 # If your system has a battery (set_use_battery=True), the charge efficiency
Enom: 5000 # If your system has a battery (set_use_battery=True), the total capacity of the battery stack in Wh
SOCmin: 0.3 # If your system has a battery (set_use_battery=True), the minimun allowable battery state of charge
SOCmax: 0.9 # If your system has a battery (set_use_battery=True), the minimun allowable battery state of charge
SOCtarget: 0.6 # If your system has a battery (set_use_battery=True), the desired battery state of charge at the end of each optimization cycle
Binary file added data/data_train_load_clustering.pkl
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = 'David HERNANDEZ'

# The full version, including alpha/beta/rc tags
release = '0.6.2'
release = '0.7.0'

# -- General configuration ---------------------------------------------------

Expand Down
Loading

0 comments on commit 6bc4df4

Please sign in to comment.