emhass 0.4.8__py3-none-any.whl → 0.4.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- emhass/command_line.py +14 -0
- emhass/machine_learning_forecaster.py +1 -1
- emhass/utils.py +7 -1
- emhass/web_server.py +10 -3
- {emhass-0.4.8.dist-info → emhass-0.4.10.dist-info}/METADATA +18 -11
- emhass-0.4.10.dist-info/RECORD +15 -0
- emhass-0.4.8.dist-info/RECORD +0 -15
- {emhass-0.4.8.dist-info → emhass-0.4.10.dist-info}/WHEEL +0 -0
- {emhass-0.4.8.dist-info → emhass-0.4.10.dist-info}/entry_points.txt +0 -0
- {emhass-0.4.8.dist-info → emhass-0.4.10.dist-info}/top_level.txt +0 -0
emhass/command_line.py
CHANGED
@@ -517,6 +517,20 @@ def publish_data(input_data_dict: dict, logger: logging.Logger,
|
|
517
517
|
custom_cost_fun_id["entity_id"],
|
518
518
|
custom_cost_fun_id["unit_of_measurement"],
|
519
519
|
custom_cost_fun_id["friendly_name"])
|
520
|
+
# Publish unit_load_cost
|
521
|
+
custom_unit_load_cost_id = params['passed_data']['custom_unit_load_cost_id']
|
522
|
+
input_data_dict['rh'].post_data(opt_res_latest['unit_load_cost'], idx_closest,
|
523
|
+
custom_unit_load_cost_id["entity_id"],
|
524
|
+
custom_unit_load_cost_id["unit_of_measurement"],
|
525
|
+
custom_unit_load_cost_id["friendly_name"])
|
526
|
+
cols_published = cols_published+["unit_load_cost"]
|
527
|
+
# Publish unit_prod_price
|
528
|
+
custom_unit_prod_price_id = params['passed_data']['custom_unit_prod_price_id']
|
529
|
+
input_data_dict['rh'].post_data(opt_res_latest['unit_prod_price'], idx_closest,
|
530
|
+
custom_unit_prod_price_id["entity_id"],
|
531
|
+
custom_unit_prod_price_id["unit_of_measurement"],
|
532
|
+
custom_unit_prod_price_id["friendly_name"])
|
533
|
+
cols_published = cols_published+["unit_prod_price"]
|
520
534
|
# Create a DF resuming what has been published
|
521
535
|
opt_res = opt_res_latest[cols_published].loc[[opt_res_latest.index[idx_closest]]]
|
522
536
|
return opt_res
|
@@ -117,7 +117,7 @@ class mlforecaster:
|
|
117
117
|
self.data_exo[self.var_model] = self.data[self.var_model]
|
118
118
|
self.data_exo = self.data_exo.interpolate(method='linear', axis=0, limit=None)
|
119
119
|
# train/test split
|
120
|
-
self.date_train = self.data_exo.index[-1]-pd.Timedelta('
|
120
|
+
self.date_train = self.data_exo.index[-1]-pd.Timedelta('5days')+self.data_exo.index.freq # The last 5 days
|
121
121
|
self.date_split = self.data_exo.index[-1]-pd.Timedelta(split_date_delta)+self.data_exo.index.freq # The last 48h
|
122
122
|
self.data_train = self.data_exo.loc[:self.date_split,:]
|
123
123
|
self.data_test = self.data_exo.loc[self.date_split:,:]
|
emhass/utils.py
CHANGED
@@ -136,6 +136,8 @@ def treat_runtimeparams(runtimeparams: str, params: str, retrieve_hass_conf: dic
|
|
136
136
|
'custom_batt_soc_forecast_id': {"entity_id": "sensor.soc_batt_forecast", "unit_of_measurement": "%", "friendly_name": "Battery SOC Forecast"},
|
137
137
|
'custom_grid_forecast_id': {"entity_id": "sensor.p_grid_forecast", "unit_of_measurement": "W", "friendly_name": "Grid Power Forecast"},
|
138
138
|
'custom_cost_fun_id': {"entity_id": "sensor.total_cost_fun_value", "unit_of_measurement": "", "friendly_name": "Total cost function value"},
|
139
|
+
'custom_unit_load_cost_id': {"entity_id": "sensor.unit_load_cost", "unit_of_measurement": "€/kWh", "friendly_name": "Unit Load Cost"},
|
140
|
+
'custom_unit_prod_price_id': {"entity_id": "sensor.unit_prod_price", "unit_of_measurement": "€/kWh", "friendly_name": "Unit Prod Price"},
|
139
141
|
'custom_deferrable_forecast_id': custom_deferrable_forecast_id}
|
140
142
|
if 'passed_data' in params.keys():
|
141
143
|
for key, value in default_passed_dict.items():
|
@@ -246,7 +248,7 @@ def treat_runtimeparams(runtimeparams: str, params: str, retrieve_hass_conf: dic
|
|
246
248
|
params['passed_data']['prod_price_forecast'] = None
|
247
249
|
# Treat passed data for forecast model fit/predict/tune at runtime
|
248
250
|
if 'days_to_retrieve' not in runtimeparams.keys():
|
249
|
-
days_to_retrieve =
|
251
|
+
days_to_retrieve = 9
|
250
252
|
else:
|
251
253
|
days_to_retrieve = runtimeparams['days_to_retrieve']
|
252
254
|
params['passed_data']['days_to_retrieve'] = days_to_retrieve
|
@@ -333,6 +335,10 @@ def treat_runtimeparams(runtimeparams: str, params: str, retrieve_hass_conf: dic
|
|
333
335
|
params['passed_data']['custom_grid_forecast_id'] = runtimeparams['custom_grid_forecast_id']
|
334
336
|
if 'custom_cost_fun_id' in runtimeparams.keys():
|
335
337
|
params['passed_data']['custom_cost_fun_id'] = runtimeparams['custom_cost_fun_id']
|
338
|
+
if 'custom_unit_load_cost_id' in runtimeparams.keys():
|
339
|
+
params['passed_data']['custom_unit_load_cost_id'] = runtimeparams['custom_unit_load_cost_id']
|
340
|
+
if 'custom_unit_prod_price_id' in runtimeparams.keys():
|
341
|
+
params['passed_data']['custom_unit_prod_price_id'] = runtimeparams['custom_unit_prod_price_id']
|
336
342
|
if 'custom_deferrable_forecast_id' in runtimeparams.keys():
|
337
343
|
params['passed_data']['custom_deferrable_forecast_id'] = runtimeparams['custom_deferrable_forecast_id']
|
338
344
|
# Serialize the final params
|
emhass/web_server.py
CHANGED
@@ -30,16 +30,23 @@ app.logger.addHandler(ch)
|
|
30
30
|
def get_injection_dict(df, plot_size = 1366):
|
31
31
|
# Create plots
|
32
32
|
cols_p = [i for i in df.columns.to_list() if 'P_' in i]
|
33
|
+
n_colors = len(cols_p)
|
34
|
+
colors = px.colors.sample_colorscale("jet", [n/(n_colors -1) for n in range(n_colors)])
|
33
35
|
fig_0 = px.line(df[cols_p], title='Systems powers schedule after optimization results',
|
34
|
-
template='presentation', width=plot_size, height=0.5*plot_size, line_shape="hv"
|
36
|
+
template='presentation', width=plot_size, height=0.5*plot_size, line_shape="hv",
|
37
|
+
color_discrete_sequence=colors)
|
35
38
|
fig_0.update_layout(xaxis_title='Timestamp', yaxis_title='System powers (W)')
|
36
39
|
if 'SOC_opt' in df.columns.to_list():
|
37
40
|
fig_1 = px.line(df['SOC_opt'], title='Battery state of charge schedule after optimization results',
|
38
|
-
template='presentation', width=plot_size, height=0.5*plot_size, line_shape="hv"
|
41
|
+
template='presentation', width=plot_size, height=0.5*plot_size, line_shape="hv",
|
42
|
+
color_discrete_sequence=colors)
|
39
43
|
fig_1.update_layout(xaxis_title='Timestamp', yaxis_title='Battery SOC (%)')
|
40
44
|
cols_cost = [i for i in df.columns.to_list() if 'cost_' in i or 'unit_' in i]
|
45
|
+
n_colors = len(cols_cost)
|
46
|
+
colors = px.colors.sample_colorscale("jet", [n/(n_colors -1) for n in range(n_colors)])
|
41
47
|
fig_2 = px.line(df[cols_cost], title='Systems costs obtained from optimization results',
|
42
|
-
|
48
|
+
template='presentation', width=plot_size, height=0.5*plot_size, line_shape="hv",
|
49
|
+
color_discrete_sequence=colors)
|
43
50
|
fig_2.update_layout(xaxis_title='Timestamp', yaxis_title='System costs (currency)')
|
44
51
|
# Get full path to image
|
45
52
|
image_path_0 = fig_0.to_html(full_html=False, default_width='75%')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: emhass
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.10
|
4
4
|
Summary: An Energy Management System for Home Assistant
|
5
5
|
Home-page: https://github.com/davidusb-geek/emhass
|
6
6
|
Author: David HERNANDEZ
|
@@ -67,22 +67,27 @@ EHMASS is a Python module designed to optimize your home energy interfacing with
|
|
67
67
|
|
68
68
|
## Introduction
|
69
69
|
|
70
|
-
|
71
|
-
The main dependencies of this project are PVLib to model power from a PV residential installation and the PuLP Python package to perform the actual optimizations using the Linear Programming approach.
|
70
|
+
EMHASS (Energy Management for Home Assistant) is an optimization tool designed for residential households. The package uses a Linear Programming approach to optimize energy usage while considering factors such as electricity prices, power generation from solar panels, and energy storage from batteries. EMHASS provides a high degree of configurability, making it easy to integrate with Home Assistant and other smart home systems. Whether you have solar panels, energy storage, or just a controllable load, EMHASS can provide an optimized daily schedule for your devices, allowing you to save money and minimize your environmental impact.
|
72
71
|
|
73
72
|
The complete documentation for this package is [available here](https://emhass.readthedocs.io/en/latest/).
|
74
73
|
|
75
|
-
## What is
|
74
|
+
## What is Energy Management for Home Assistant (EMHASS)?
|
76
75
|
|
77
|
-
|
76
|
+
EMHASS and Home Assistant provide a comprehensive energy management solution that can optimize energy usage and reduce costs for households. By integrating these two systems, households can take advantage of advanced energy management features that provide significant cost savings, increased energy efficiency, and greater sustainability.
|
78
77
|
|
79
|
-
|
78
|
+
EMHASS is a powerful energy management tool that generates an optimization plan based on variables such as solar power production, energy usage, and energy costs. The plan provides valuable insights into how energy can be better managed and utilized in the household. Even if households do not have all the necessary equipment, such as solar panels or batteries, EMHASS can still provide a minimal use case solution to optimize energy usage for controllable/deferrable loads.
|
79
|
+
|
80
|
+
Home Assistant provides a platform for the automation of household devices based on the optimization plan generated by EMHASS. This includes devices such as batteries, pool pumps, hot water heaters, and electric vehicle (EV) chargers. By automating EV charging and other devices, households can take advantage of off-peak energy rates and optimize their EV charging schedule based on the optimization plan generated by EMHASS.
|
81
|
+
|
82
|
+
One of the main benefits of integrating EMHASS and Home Assistant is the ability to customize and tailor the energy management solution to the specific needs and preferences of each household. With EMHASS, households can define their energy management objectives and constraints, such as maximizing self-consumption or minimizing energy costs, and the system will generate an optimization plan accordingly. Home Assistant provides a platform for the automation of devices based on the optimization plan, allowing households to create a fully customized and optimized energy management solution.
|
83
|
+
|
84
|
+
Overall, the integration of EMHASS and Home Assistant offers a comprehensive energy management solution that provides significant cost savings, increased energy efficiency, and greater sustainability for households. By leveraging advanced energy management features and automation capabilities, households can achieve their energy management objectives while enjoying the benefits of a more efficient and sustainable energy usage, including optimized EV charging schedules.
|
80
85
|
|
81
86
|
The package flow can be graphically represented as follows:
|
82
87
|
|
83
88
|

|
84
89
|
|
85
|
-
|
90
|
+
## Configuration and Installation
|
86
91
|
|
87
92
|
The package is meant to be highly configurable with an object oriented modular approach and a main configuration file defined by the user.
|
88
93
|
EMHASS was designed to be integrated with Home Assistant, hence it's name.
|
@@ -104,8 +109,6 @@ A more detailed workflow is given below:
|
|
104
109
|
|
105
110
|

|
106
111
|
|
107
|
-
## Installation
|
108
|
-
|
109
112
|
### Method 1) The EMHASS add-on for Home Assistant OS and supervised users
|
110
113
|
|
111
114
|
For Home Assistant OS and HA Supervised users, I've developed an add-on that will help you use EMHASS. The add-on is more user friendly as the configuration can be modified directly in the add-on options pane and as with the standalone docker it exposes a web ui that can be used to inspect the optimization results and manually trigger a new optimization.
|
@@ -171,12 +174,15 @@ python3 -m pip install --upgrade emhass
|
|
171
174
|
|
172
175
|
If using the add-on or the standalone docker installation, it exposes a simple webserver on port 5000. You can access it directly using your brower, ex: http://localhost:5000.
|
173
176
|
|
174
|
-
With this web server you can perform RESTful POST commands on
|
177
|
+
With this web server you can perform RESTful POST commands on multiple ENDPOINTS with prefix `action/*`:
|
175
178
|
|
176
179
|
- A POST call to `action/perfect-optim` to perform a perfect optimization task on the historical data.
|
177
180
|
- A POST call to `action/dayahead-optim` to perform a day-ahead optimization task of your home energy.
|
178
181
|
- A POST call to `action/naive-mpc-optim` to perform a naive Model Predictive Controller optimization task. If using this option you will need to define the correct `runtimeparams` (see further below).
|
179
182
|
- A POST call to `action/publish-data` to publish the optimization results data for the current timestamp.
|
183
|
+
- A POST call to `action/forecast-model-fit` to train a machine learning forecaster model with the passed data (see the [dedicated section](https://emhass.readthedocs.io/en/latest/mlforecaster.html) for more help).
|
184
|
+
- A POST call to `action/forecast-model-predict` to obtain a forecast from a pre-trained machine learning forecaster model (see the [dedicated section](https://emhass.readthedocs.io/en/latest/mlforecaster.html) for more help).
|
185
|
+
- A POST call to `action/forecast-model-tune` to optimize the machine learning forecaster models hyperparameters using bayesian optimization (see the [dedicated section](https://emhass.readthedocs.io/en/latest/mlforecaster.html) for more help).
|
180
186
|
|
181
187
|
A `curl` command can then be used to launch an optimization task like this: `curl -i -H 'Content-Type:application/json' -X POST -d '{}' http://localhost:5000/action/dayahead-optim`.
|
182
188
|
|
@@ -184,12 +190,13 @@ A `curl` command can then be used to launch an optimization task like this: `cur
|
|
184
190
|
|
185
191
|
To run a command simply use the `emhass` CLI command followed by the needed arguments.
|
186
192
|
The available arguments are:
|
187
|
-
- `--action`: That is used to set the desired action, options are: `perfect-optim`, `dayahead-optim`, `naive-mpc-optim` and `
|
193
|
+
- `--action`: That is used to set the desired action, options are: `perfect-optim`, `dayahead-optim`, `naive-mpc-optim`, `publish-data`, `forecast-model-fit`, `forecast-model-predict` and `forecast-model-tune`.
|
188
194
|
- `--config`: Define path to the config.yaml file (including the yaml file itself)
|
189
195
|
- `--costfun`: Define the type of cost function, this is optional and the options are: `profit` (default), `cost`, `self-consumption`
|
190
196
|
- `--log2file`: Define if we should log to a file or not, this is optional and the options are: `True` or `False` (default)
|
191
197
|
- `--params`: Configuration as JSON.
|
192
198
|
- `--runtimeparams`: Data passed at runtime. This can be used to pass your own forecast data to EMHASS.
|
199
|
+
- `--debug`: Use `True` for testing purposes.
|
193
200
|
- `--version`: Show the current version of EMHASS.
|
194
201
|
|
195
202
|
For example, the following line command can be used to perform a day-ahead optimization task:
|
@@ -0,0 +1,15 @@
|
|
1
|
+
emhass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
emhass/command_line.py,sha256=QSxkOmmjTEBcBwOo7C4p70_pHPHtpqJmHi7ZmBGgF3M,34580
|
3
|
+
emhass/forecast.py,sha256=mJY846P_VWK_Ov-F-SZg_We55Y799a5b8Lwo1bO_JK8,43072
|
4
|
+
emhass/machine_learning_forecaster.py,sha256=C0k3bkq0pXRmfwIMigrh0aI2ZRO-qa7WFtDcPoGwFEQ,14964
|
5
|
+
emhass/optimization.py,sha256=QL9LpOhhpo_YgmF3_lvXWPGdz-ZeH62_zUCwm2swlyM,30582
|
6
|
+
emhass/retrieve_hass.py,sha256=lsLSiWB2XC1TTlAw_GR7YWjVXti4ZXKhICROST8UlTw,15888
|
7
|
+
emhass/utils.py,sha256=M1-E0o-X0D1uOrKARRTnvhzosd3pYCkPjbEvumc34Ic,23116
|
8
|
+
emhass/web_server.py,sha256=z4oFYG_rzVhhyCd7vOLsJWM2LG8pbdPMJMmJpmwH7JI,18654
|
9
|
+
emhass/static/style.css,sha256=5qGJl0MZGSaSvr0HUcGQ9UgMtDKP2CiyE-1H-jbsLuU,6760
|
10
|
+
emhass/templates/index.html,sha256=DGP5PayjyDJnZo9LYRrGg0pYIfr-AwwITgKocmUbruU,6615
|
11
|
+
emhass-0.4.10.dist-info/METADATA,sha256=tfIyU_0oLp1IYVLI1PjrURM-1NXMkxL96jtdG5uVVH4,27318
|
12
|
+
emhass-0.4.10.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
13
|
+
emhass-0.4.10.dist-info/entry_points.txt,sha256=tJULCm7mHGYb_IxyzPN_4KFYvhxv209_jq68jPiByy0,53
|
14
|
+
emhass-0.4.10.dist-info/top_level.txt,sha256=L7fIX4awfmxQbAePtSdVg2e6x_HhghfReHfsKSpKr9I,7
|
15
|
+
emhass-0.4.10.dist-info/RECORD,,
|
emhass-0.4.8.dist-info/RECORD
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
emhass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
emhass/command_line.py,sha256=IbHexJGwDnqDVvRN1V07QXmE5sm1XtO8oHhBjp87Fi4,33594
|
3
|
-
emhass/forecast.py,sha256=mJY846P_VWK_Ov-F-SZg_We55Y799a5b8Lwo1bO_JK8,43072
|
4
|
-
emhass/machine_learning_forecaster.py,sha256=FaWZv8aMS8ihx1Z6RhY6yuNkbkouZV8CujXAMmcFnAI,14966
|
5
|
-
emhass/optimization.py,sha256=QL9LpOhhpo_YgmF3_lvXWPGdz-ZeH62_zUCwm2swlyM,30582
|
6
|
-
emhass/retrieve_hass.py,sha256=lsLSiWB2XC1TTlAw_GR7YWjVXti4ZXKhICROST8UlTw,15888
|
7
|
-
emhass/utils.py,sha256=_EuITuTur7RwI3_oBRWEmEQk1F_Ke1wZ4pOSp57VRC4,22445
|
8
|
-
emhass/web_server.py,sha256=wQT0HD8N86zC2V28L4zVUqVfP6sj0U-ZmltoUc51rXs,18255
|
9
|
-
emhass/static/style.css,sha256=5qGJl0MZGSaSvr0HUcGQ9UgMtDKP2CiyE-1H-jbsLuU,6760
|
10
|
-
emhass/templates/index.html,sha256=DGP5PayjyDJnZo9LYRrGg0pYIfr-AwwITgKocmUbruU,6615
|
11
|
-
emhass-0.4.8.dist-info/METADATA,sha256=ppNVOXjCPNrfU2_zHH4FLCuf7tibxEQUm0jbTeoeYqM,24995
|
12
|
-
emhass-0.4.8.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
13
|
-
emhass-0.4.8.dist-info/entry_points.txt,sha256=tJULCm7mHGYb_IxyzPN_4KFYvhxv209_jq68jPiByy0,53
|
14
|
-
emhass-0.4.8.dist-info/top_level.txt,sha256=L7fIX4awfmxQbAePtSdVg2e6x_HhghfReHfsKSpKr9I,7
|
15
|
-
emhass-0.4.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|