emhass 0.4.12__py3-none-any.whl → 0.4.14__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 CHANGED
@@ -54,7 +54,7 @@ def set_input_data_dict(config_path: pathlib.Path, base_path: str, costfun: str,
54
54
  retrieve_hass_conf, optim_conf, plant_conf = utils.get_yaml_parse(
55
55
  config_path, use_secrets=not(get_data_from_file), params=params)
56
56
  # Treat runtimeparams
57
- params, retrieve_hass_conf, optim_conf = utils.treat_runtimeparams(
57
+ params, retrieve_hass_conf, optim_conf, plant_conf = utils.treat_runtimeparams(
58
58
  runtimeparams, params, retrieve_hass_conf,
59
59
  optim_conf, plant_conf, set_type, logger)
60
60
  # Define main objects
@@ -364,6 +364,7 @@ def forecast_model_predict(input_data_dict: dict, logger: logging.Logger,
364
364
  model_predict_entity_id = input_data_dict['params']['passed_data']['model_predict_entity_id']
365
365
  model_predict_unit_of_measurement = input_data_dict['params']['passed_data']['model_predict_unit_of_measurement']
366
366
  model_predict_friendly_name = input_data_dict['params']['passed_data']['model_predict_friendly_name']
367
+ publish_prefix = input_data_dict['params']['passed_data']['publish_prefix']
367
368
  if model_predict_publish:
368
369
  # Estimate the current index
369
370
  now_precise = datetime.now(input_data_dict['retrieve_hass_conf']['time_zone']).replace(second=0, microsecond=0)
@@ -380,7 +381,8 @@ def forecast_model_predict(input_data_dict: dict, logger: logging.Logger,
380
381
  model_predict_entity_id,
381
382
  model_predict_unit_of_measurement,
382
383
  model_predict_friendly_name,
383
- from_mlforecaster=True)
384
+ type_var = 'mlforecaster',
385
+ publish_prefix=publish_prefix)
384
386
  return predictions
385
387
 
386
388
  def forecast_model_tune(input_data_dict: dict, logger: logging.Logger,
@@ -462,19 +464,25 @@ def publish_data(input_data_dict: dict, logger: logging.Logger,
462
464
  idx_closest = opt_res_latest.index.get_indexer([now_precise], method='bfill')[0]
463
465
  if idx_closest == -1:
464
466
  idx_closest = opt_res_latest.index.get_indexer([now_precise], method='nearest')[0]
465
- # Publish PV forecast
467
+ # Publish the data
466
468
  params = json.loads(input_data_dict['params'])
469
+ publish_prefix = params['passed_data']['publish_prefix']
470
+ # Publish PV forecast
467
471
  custom_pv_forecast_id = params['passed_data']['custom_pv_forecast_id']
468
472
  input_data_dict['rh'].post_data(opt_res_latest['P_PV'], idx_closest,
469
473
  custom_pv_forecast_id["entity_id"],
470
474
  custom_pv_forecast_id["unit_of_measurement"],
471
- custom_pv_forecast_id["friendly_name"])
475
+ custom_pv_forecast_id["friendly_name"],
476
+ type_var = 'power',
477
+ publish_prefix=publish_prefix)
472
478
  # Publish Load forecast
473
479
  custom_load_forecast_id = params['passed_data']['custom_load_forecast_id']
474
480
  input_data_dict['rh'].post_data(opt_res_latest['P_Load'], idx_closest,
475
481
  custom_load_forecast_id["entity_id"],
476
482
  custom_load_forecast_id["unit_of_measurement"],
477
- custom_load_forecast_id["friendly_name"])
483
+ custom_load_forecast_id["friendly_name"],
484
+ type_var = 'power',
485
+ publish_prefix=publish_prefix)
478
486
  cols_published = ['P_PV', 'P_Load']
479
487
  # Publish deferrable loads
480
488
  custom_deferrable_forecast_id = params['passed_data']['custom_deferrable_forecast_id']
@@ -485,7 +493,9 @@ def publish_data(input_data_dict: dict, logger: logging.Logger,
485
493
  input_data_dict['rh'].post_data(opt_res_latest["P_deferrable{}".format(k)], idx_closest,
486
494
  custom_deferrable_forecast_id[k]["entity_id"],
487
495
  custom_deferrable_forecast_id[k]["unit_of_measurement"],
488
- custom_deferrable_forecast_id[k]["friendly_name"])
496
+ custom_deferrable_forecast_id[k]["friendly_name"],
497
+ type_var = 'deferrable',
498
+ publish_prefix=publish_prefix)
489
499
  cols_published = cols_published+["P_deferrable{}".format(k)]
490
500
  # Publish battery power
491
501
  if input_data_dict['opt'].optim_conf['set_use_battery']:
@@ -496,20 +506,26 @@ def publish_data(input_data_dict: dict, logger: logging.Logger,
496
506
  input_data_dict['rh'].post_data(opt_res_latest['P_batt'], idx_closest,
497
507
  custom_batt_forecast_id["entity_id"],
498
508
  custom_batt_forecast_id["unit_of_measurement"],
499
- custom_batt_forecast_id["friendly_name"])
509
+ custom_batt_forecast_id["friendly_name"],
510
+ type_var = 'batt',
511
+ publish_prefix=publish_prefix)
500
512
  cols_published = cols_published+["P_batt"]
501
513
  custom_batt_soc_forecast_id = params['passed_data']['custom_batt_soc_forecast_id']
502
514
  input_data_dict['rh'].post_data(opt_res_latest['SOC_opt']*100, idx_closest,
503
515
  custom_batt_soc_forecast_id["entity_id"],
504
516
  custom_batt_soc_forecast_id["unit_of_measurement"],
505
- custom_batt_soc_forecast_id["friendly_name"])
517
+ custom_batt_soc_forecast_id["friendly_name"],
518
+ type_var = 'SOC',
519
+ publish_prefix=publish_prefix)
506
520
  cols_published = cols_published+["SOC_opt"]
507
521
  # Publish grid power
508
522
  custom_grid_forecast_id = params['passed_data']['custom_grid_forecast_id']
509
523
  input_data_dict['rh'].post_data(opt_res_latest['P_grid'], idx_closest,
510
524
  custom_grid_forecast_id["entity_id"],
511
525
  custom_grid_forecast_id["unit_of_measurement"],
512
- custom_grid_forecast_id["friendly_name"])
526
+ custom_grid_forecast_id["friendly_name"],
527
+ type_var = 'power',
528
+ publish_prefix=publish_prefix)
513
529
  cols_published = cols_published+["P_grid"]
514
530
  # Publish total value of cost function
515
531
  custom_cost_fun_id = params['passed_data']['custom_cost_fun_id']
@@ -517,20 +533,26 @@ def publish_data(input_data_dict: dict, logger: logging.Logger,
517
533
  input_data_dict['rh'].post_data(opt_res_latest[col_cost_fun], idx_closest,
518
534
  custom_cost_fun_id["entity_id"],
519
535
  custom_cost_fun_id["unit_of_measurement"],
520
- custom_cost_fun_id["friendly_name"])
536
+ custom_cost_fun_id["friendly_name"],
537
+ type_var = 'cost_fun',
538
+ publish_prefix=publish_prefix)
521
539
  # Publish unit_load_cost
522
540
  custom_unit_load_cost_id = params['passed_data']['custom_unit_load_cost_id']
523
541
  input_data_dict['rh'].post_data(opt_res_latest['unit_load_cost'], idx_closest,
524
542
  custom_unit_load_cost_id["entity_id"],
525
543
  custom_unit_load_cost_id["unit_of_measurement"],
526
- custom_unit_load_cost_id["friendly_name"])
544
+ custom_unit_load_cost_id["friendly_name"],
545
+ type_var = 'unit_load_cost',
546
+ publish_prefix=publish_prefix)
527
547
  cols_published = cols_published+["unit_load_cost"]
528
548
  # Publish unit_prod_price
529
549
  custom_unit_prod_price_id = params['passed_data']['custom_unit_prod_price_id']
530
550
  input_data_dict['rh'].post_data(opt_res_latest['unit_prod_price'], idx_closest,
531
551
  custom_unit_prod_price_id["entity_id"],
532
552
  custom_unit_prod_price_id["unit_of_measurement"],
533
- custom_unit_prod_price_id["friendly_name"])
553
+ custom_unit_prod_price_id["friendly_name"],
554
+ type_var = 'unit_prod_price',
555
+ publish_prefix=publish_prefix)
534
556
  cols_published = cols_published+["unit_prod_price"]
535
557
  # Create a DF resuming what has been published
536
558
  opt_res = opt_res_latest[cols_published].loc[[opt_res_latest.index[idx_closest]]]
@@ -200,6 +200,7 @@ class mlforecaster:
200
200
  if data_last_window is None:
201
201
  predictions = self.forecaster.predict(steps=self.num_lags, exog=self.data_test.drop(self.var_model, axis=1))
202
202
  else:
203
+ data_last_window = data_last_window.interpolate(method='linear', axis=0, limit=None)
203
204
  if self.is_tuned:
204
205
  exog = mlforecaster.generate_exog(data_last_window, self.lags_opt, self.var_model)
205
206
  predictions = self.forecaster.predict(steps=self.lags_opt,
emhass/retrieve_hass.py CHANGED
@@ -223,7 +223,7 @@ class retrieve_hass:
223
223
  list_df = copy.deepcopy(data_df).loc[data_df.index[idx]:].reset_index()
224
224
  list_df.columns = ['timestamps', entity_id]
225
225
  ts_list = [str(i) for i in list_df['timestamps'].tolist()]
226
- vals_list = [str(np.round(i)) for i in list_df[entity_id].tolist()]
226
+ vals_list = [str(np.round(i,2)) for i in list_df[entity_id].tolist()]
227
227
  forecast_list = []
228
228
  for i, ts in enumerate(ts_list):
229
229
  datum = {}
@@ -231,7 +231,7 @@ class retrieve_hass:
231
231
  datum[entity_id.split('sensor.')[1]] = vals_list[i]
232
232
  forecast_list.append(datum)
233
233
  data = {
234
- "state": str(state),
234
+ "state": "{:.2f}".format(state),
235
235
  "attributes": {
236
236
  "unit_of_measurement": unit_of_measurement,
237
237
  "friendly_name": friendly_name,
@@ -242,7 +242,9 @@ class retrieve_hass:
242
242
 
243
243
  def post_data(self, data_df: pd.DataFrame, idx: int, entity_id: str,
244
244
  unit_of_measurement: str, friendly_name: str,
245
- from_mlforecaster: Optional[bool]=False) -> None:
245
+ type_var: str,
246
+ from_mlforecaster: Optional[bool]=False,
247
+ publish_prefix: Optional[str]="") -> None:
246
248
  r"""
247
249
  Post passed data to hass.
248
250
 
@@ -258,8 +260,15 @@ class retrieve_hass:
258
260
  :type unit_of_measurement: str
259
261
  :param friendly_name: The friendly name that will be used in the hass frontend.
260
262
  :type friendly_name: str
263
+ :param type_var: A variable to indicate the type of variable: power, SOC, etc.
264
+ :type type_var: str
265
+ :param publish_prefix: A common prefix for all published data entity_id.
266
+ :type publish_prefix: str, optional
261
267
 
262
268
  """
269
+ # Add a possible prefix to the entity ID
270
+ entity_id = entity_id.replace('sensor.', 'sensor.'+publish_prefix)
271
+ # Set the URL
263
272
  if self.hass_url == "http://supervisor/core/api": # If we are using the supervisor API
264
273
  url = self.hass_url+"/states/"+entity_id
265
274
  else: # Otherwise the Home Assistant Core API it is
@@ -269,34 +278,36 @@ class retrieve_hass:
269
278
  "content-type": "application/json",
270
279
  }
271
280
  # Preparing the data dict to be published
272
- if 'cost_fun_' in entity_id:
281
+ if type_var == 'cost_fun':
273
282
  state = np.round(data_df.sum()[0],2)
283
+ elif type_var == 'unit_load_cost' or type_var == 'unit_prod_price':
284
+ state = np.round(data_df.loc[data_df.index[idx]],4)
274
285
  else:
275
286
  state = np.round(data_df.loc[data_df.index[idx]],2)
276
- if 'p_pv' in entity_id or 'p_load' in entity_id or 'p_grid' in entity_id:
287
+ if type_var == 'power':
277
288
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
278
289
  friendly_name, "forecasts", state)
279
- elif 'deferrable' in entity_id:
290
+ elif type_var == 'deferrable':
280
291
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
281
292
  friendly_name, "deferrables_schedule", state)
282
- elif 'batt' in entity_id:
293
+ elif type_var == 'batt':
283
294
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
284
295
  friendly_name, "battery_scheduled_power", state)
285
- elif 'SOC' in entity_id:
296
+ elif type_var == 'SOC':
286
297
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
287
298
  friendly_name, "battery_scheduled_soc", state)
288
- elif 'unit_load_cost' in entity_id:
299
+ elif type_var == 'unit_load_cost':
289
300
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
290
301
  friendly_name, "unit_load_cost_forecasts", state)
291
- elif 'unit_prod_price' in entity_id:
302
+ elif type_var == 'unit_prod_price':
292
303
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
293
- friendly_name, "unit_load_cost_forecasts", state)
294
- elif from_mlforecaster:
304
+ friendly_name, "unit_prod_price_forecasts", state)
305
+ elif type_var == 'mlforecaster':
295
306
  data = retrieve_hass.get_attr_data_dict(data_df, idx, entity_id, unit_of_measurement,
296
307
  friendly_name, "scheduled_forecast", state)
297
308
  else:
298
309
  data = {
299
- "state": str(state),
310
+ "state": "{:.2f}".format(state),
300
311
  "attributes": {
301
312
  "unit_of_measurement": unit_of_measurement,
302
313
  "friendly_name": friendly_name
emhass/utils.py CHANGED
@@ -138,7 +138,8 @@ def treat_runtimeparams(runtimeparams: str, params: str, retrieve_hass_conf: dic
138
138
  'custom_cost_fun_id': {"entity_id": "sensor.total_cost_fun_value", "unit_of_measurement": "", "friendly_name": "Total cost function value"},
139
139
  'custom_unit_load_cost_id': {"entity_id": "sensor.unit_load_cost", "unit_of_measurement": "€/kWh", "friendly_name": "Unit Load Cost"},
140
140
  'custom_unit_prod_price_id': {"entity_id": "sensor.unit_prod_price", "unit_of_measurement": "€/kWh", "friendly_name": "Unit Prod Price"},
141
- 'custom_deferrable_forecast_id': custom_deferrable_forecast_id}
141
+ 'custom_deferrable_forecast_id': custom_deferrable_forecast_id,
142
+ 'publish_prefix': ""}
142
143
  if 'passed_data' in params.keys():
143
144
  for key, value in default_passed_dict.items():
144
145
  params['passed_data'][key] = value
@@ -322,6 +323,9 @@ def treat_runtimeparams(runtimeparams: str, params: str, retrieve_hass_conf: dic
322
323
  if 'solar_forecast_kwp' in runtimeparams.keys():
323
324
  retrieve_hass_conf['solar_forecast_kwp'] = runtimeparams['solar_forecast_kwp']
324
325
  optim_conf['weather_forecast_method'] = 'solar.forecast'
326
+ # Treat plant configuration parameters passed at runtime
327
+ if 'SOCtarget' in runtimeparams.keys():
328
+ plant_conf['SOCtarget'] = runtimeparams['SOCtarget']
325
329
  # Treat custom entities id's and friendly names for variables
326
330
  if 'custom_pv_forecast_id' in runtimeparams.keys():
327
331
  params['passed_data']['custom_pv_forecast_id'] = runtimeparams['custom_pv_forecast_id']
@@ -341,9 +345,15 @@ def treat_runtimeparams(runtimeparams: str, params: str, retrieve_hass_conf: dic
341
345
  params['passed_data']['custom_unit_prod_price_id'] = runtimeparams['custom_unit_prod_price_id']
342
346
  if 'custom_deferrable_forecast_id' in runtimeparams.keys():
343
347
  params['passed_data']['custom_deferrable_forecast_id'] = runtimeparams['custom_deferrable_forecast_id']
348
+ # A condition to put a prefix on all published data
349
+ if 'publish_prefix' not in runtimeparams.keys():
350
+ publish_prefix = ""
351
+ else:
352
+ publish_prefix = runtimeparams['publish_prefix']
353
+ params['passed_data']['publish_prefix'] = publish_prefix
344
354
  # Serialize the final params
345
355
  params = json.dumps(params)
346
- return params, retrieve_hass_conf, optim_conf
356
+ return params, retrieve_hass_conf, optim_conf, plant_conf
347
357
 
348
358
  def get_yaml_parse(config_path: str, use_secrets: Optional[bool] = True,
349
359
  params: Optional[str] = None) -> Tuple[dict, dict, dict]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: emhass
3
- Version: 0.4.12
3
+ Version: 0.4.14
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
@@ -8,13 +8,13 @@ Author-email: davidusb@gmail.com
8
8
  License: UNKNOWN
9
9
  Keywords: energy,management,optimization,hass
10
10
  Platform: UNKNOWN
11
- Classifier: Development Status :: 4 - Beta
11
+ Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Topic :: Software Development :: Build Tools
14
14
  Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Operating System :: OS Independent
17
- Requires-Python: >=3.8, <3.10
17
+ Requires-Python: >=3.8, <=3.10
18
18
  Description-Content-Type: text/markdown
19
19
  Requires-Dist: wheel
20
20
  Requires-Dist: numpy (==1.22.2)
@@ -30,7 +30,7 @@ Requires-Dist: pulp (>=2.4)
30
30
  Requires-Dist: pyyaml (>=5.4.1)
31
31
  Requires-Dist: netcdf4 (>=1.5.3)
32
32
  Requires-Dist: tables (==3.7.0)
33
- Requires-Dist: skforecast (==0.8.1)
33
+ Requires-Dist: skforecast (==0.9.1)
34
34
 
35
35
  <div align="center">
36
36
  <br>
@@ -62,6 +62,15 @@ Requires-Dist: skforecast (==0.8.1)
62
62
  <img alt="Read the Docs" src="https://img.shields.io/readthedocs/emhass">
63
63
  </a>
64
64
  </p>
65
+ <br>
66
+ <p align="center">
67
+ If you like this work please consider buying a coffee ;-)
68
+ </p>
69
+ <p align="center">
70
+ <a href="https://www.buymeacoffee.com/davidusbgeek" target="_blank">
71
+ <img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" >
72
+ </a>
73
+ </p>
65
74
 
66
75
  EHMASS is a Python module designed to optimize your home energy interfacing with Home Assistant.
67
76
 
@@ -306,7 +315,7 @@ shell_command:
306
315
  publish_data: "curl -i -H \"Content-Type:application/json\" -X POST -d '{\"custom_load_forecast_id\": {\"entity_id\": \"sensor.p_load_forecast\", \"unit_of_measurement\": \"W\", \"friendly_name\": \"Load Power Forecast\"}}' http://localhost:5000/action/publish-data"
307
316
  ```
308
317
 
309
- These keys are available to modify: `custom_pv_forecast_id`, `custom_load_forecast_id`, `custom_batt_forecast_id`, `custom_batt_soc_forecast_id`, `custom_grid_forecast_id`, `custom_cost_fun_id`, `custom_deferrable_forecast_id`.
318
+ These keys are available to modify: `custom_pv_forecast_id`, `custom_load_forecast_id`, `custom_batt_forecast_id`, `custom_batt_soc_forecast_id`, `custom_grid_forecast_id`, `custom_cost_fun_id`, `custom_deferrable_forecast_id`, `custom_unit_load_cost_id` and `custom_unit_prod_price_id`.
310
319
 
311
320
  If you provide the `custom_deferrable_forecast_id` then the passed data should be a list of dictionaries, like this:
312
321
  ```
@@ -378,6 +387,10 @@ Here is the list of the other additional dictionnary keys that can be passed at
378
387
 
379
388
  - `solar_forecast_kwp` for the PV peak installed power in kW used for the solar.forecast API call.
380
389
 
390
+ - `SOCtarget` for the desired target value of initial and final SOC.
391
+
392
+ - `publish_prefix` use this key to pass a common prefix to all published data. This will add a prefix to the sensor name but also to the forecasts attributes keys within the sensor.
393
+
381
394
  ## A naive Model Predictive Controller
382
395
 
383
396
  A MPC controller was introduced in v0.3.0. This is an informal/naive representation of a MPC controller.
@@ -0,0 +1,15 @@
1
+ emhass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ emhass/command_line.py,sha256=ROab6kyZfUh7L-kVl4YbZJeOr-slPTYL5YOqPF9Y0TM,36018
3
+ emhass/forecast.py,sha256=3zqFIKwfu5cjGGLDGUZ-j1eMu8sWlSAc679oGmIwPeo,43060
4
+ emhass/machine_learning_forecaster.py,sha256=Zhs8zcTn9E5yBNjdyYDPXjd2x6iQuqtL-QgaE74ODco,15633
5
+ emhass/optimization.py,sha256=xJGtIRU3TjEtfQSDoxf-eR2OX8c74HzFz1aTDcSdlWU,31220
6
+ emhass/retrieve_hass.py,sha256=TRECIc_ZohY1MOVC5t7UjB0t9Ke3gNIn6x8ZrnBMGUo,16969
7
+ emhass/utils.py,sha256=OFb4VA7tooaUkTlqo7SPvBQPShsS5_wFE4KymJUH6KA,23644
8
+ emhass/web_server.py,sha256=zGN-xt7bh7wErbRPDQZcGEL8NWIhLlzJDKVBCdsbOP8,19684
9
+ emhass/static/style.css,sha256=5qGJl0MZGSaSvr0HUcGQ9UgMtDKP2CiyE-1H-jbsLuU,6760
10
+ emhass/templates/index.html,sha256=gdiq_mJQgiRBMEVfFyxpeqlndJJm1YprGb8R6SjS40k,6614
11
+ emhass-0.4.14.dist-info/METADATA,sha256=goup4y0hGPWtD9qeYz8w72xEgJhynGRz4OHcTY0m4xk,28137
12
+ emhass-0.4.14.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
13
+ emhass-0.4.14.dist-info/entry_points.txt,sha256=tJULCm7mHGYb_IxyzPN_4KFYvhxv209_jq68jPiByy0,53
14
+ emhass-0.4.14.dist-info/top_level.txt,sha256=L7fIX4awfmxQbAePtSdVg2e6x_HhghfReHfsKSpKr9I,7
15
+ emhass-0.4.14.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- emhass/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- emhass/command_line.py,sha256=w8_IIxfBiB3SMgO2J-vXdlToEFMcxrmW0f7chGUemy8,34589
3
- emhass/forecast.py,sha256=3zqFIKwfu5cjGGLDGUZ-j1eMu8sWlSAc679oGmIwPeo,43060
4
- emhass/machine_learning_forecaster.py,sha256=sZeo94Ss7XvewQ7BXX53i9daWl_Sc4Z-oU1K45OQEU4,15536
5
- emhass/optimization.py,sha256=xJGtIRU3TjEtfQSDoxf-eR2OX8c74HzFz1aTDcSdlWU,31220
6
- emhass/retrieve_hass.py,sha256=v5J1JpRX6lK5YyYNdoTe9LPphjYZTelPy88a0ygRoJo,16379
7
- emhass/utils.py,sha256=M1-E0o-X0D1uOrKARRTnvhzosd3pYCkPjbEvumc34Ic,23116
8
- emhass/web_server.py,sha256=zGN-xt7bh7wErbRPDQZcGEL8NWIhLlzJDKVBCdsbOP8,19684
9
- emhass/static/style.css,sha256=5qGJl0MZGSaSvr0HUcGQ9UgMtDKP2CiyE-1H-jbsLuU,6760
10
- emhass/templates/index.html,sha256=gdiq_mJQgiRBMEVfFyxpeqlndJJm1YprGb8R6SjS40k,6614
11
- emhass-0.4.12.dist-info/METADATA,sha256=XnL-du1EsCUmXXSKAE1nORXvoYaWDf0ez2QBKoJQe_o,27318
12
- emhass-0.4.12.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
13
- emhass-0.4.12.dist-info/entry_points.txt,sha256=tJULCm7mHGYb_IxyzPN_4KFYvhxv209_jq68jPiByy0,53
14
- emhass-0.4.12.dist-info/top_level.txt,sha256=L7fIX4awfmxQbAePtSdVg2e6x_HhghfReHfsKSpKr9I,7
15
- emhass-0.4.12.dist-info/RECORD,,