emhass 0.11.3__tar.gz → 0.11.4__tar.gz
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-0.11.3 → emhass-0.11.4}/CHANGELOG.md +5 -1
- {emhass-0.11.3 → emhass-0.11.4}/PKG-INFO +1 -1
- emhass-0.11.4/data/data_train_load_clustering.pkl +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/pyproject.toml +1 -1
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/utils.py +65 -55
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/web_server.py +2 -9
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass.egg-info/PKG-INFO +1 -1
- emhass-0.11.3/data/data_train_load_clustering.pkl +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/CODE_OF_CONDUCT.md +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/CONTRIBUTING.md +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/LICENSE +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/MANIFEST.in +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/README.md +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/data_load_cost_forecast.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/data_load_forecast.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/data_prod_price_forecast.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/data_train_load_forecast.pkl +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/data_weather_forecast.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/heating_prediction.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/opt_res_latest.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/opt_res_perfect_optim_cost.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/opt_res_perfect_optim_profit.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/opt_res_perfect_optim_self-consumption.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/test_df_final.pkl +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/test_response_get_data_get_method.pbz2 +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/test_response_scrapper_get_method.pbz2 +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/test_response_solarforecast_get_method.pbz2 +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/data/test_response_solcast_get_method.pbz2 +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/setup.cfg +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/__init__.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/command_line.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/data/associations.csv +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/data/cec_inverters.pbz2 +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/data/cec_modules.pbz2 +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/data/config_defaults.json +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/forecast.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/machine_learning_forecaster.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/machine_learning_regressor.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/optimization.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/retrieve_hass.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/advanced.html +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/basic.html +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/configuration_list.html +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/configuration_script.js +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/data/param_definitions.json +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/img/emhass_icon.png +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/img/emhass_logo_short.svg +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/img/feather-sprite.svg +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/script.js +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/static/style.css +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/templates/configuration.html +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/templates/index.html +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass/templates/template.html +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass.egg-info/SOURCES.txt +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass.egg-info/dependency_links.txt +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass.egg-info/entry_points.txt +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass.egg-info/requires.txt +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/src/emhass.egg-info/top_level.txt +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_command_line_utils.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_forecast.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_machine_learning_forecaster.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_machine_learning_regressor.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_optimization.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_retrieve_hass.py +0 -0
- {emhass-0.11.3 → emhass-0.11.4}/tests/test_utils.py +0 -0
@@ -1,6 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 0.11.
|
3
|
+
## 0.11.4 - 2024-12-24
|
4
|
+
### Fix
|
5
|
+
- Fix bug when treating runtime params, fix optimization_time_step timedelta
|
6
|
+
|
7
|
+
## 0.11.3 - 2024-12-23
|
4
8
|
### Improvement
|
5
9
|
- Runtime parameters now support all config parameters
|
6
10
|
- Adopted the Ruff code fomatting
|
Binary file
|
@@ -308,7 +308,7 @@ def treat_runtimeparams(
|
|
308
308
|
runtimeparams.get("optimization_time_step", runtimeparams.get("freq"))
|
309
309
|
)
|
310
310
|
params["retrieve_hass_conf"]["optimization_time_step"] = pd.to_timedelta(
|
311
|
-
optimization_time_step
|
311
|
+
optimization_time_step, "minutes"
|
312
312
|
)
|
313
313
|
else:
|
314
314
|
optimization_time_step = int(
|
@@ -338,59 +338,6 @@ def treat_runtimeparams(
|
|
338
338
|
optimization_time_step, delta_forecast, time_zone
|
339
339
|
)
|
340
340
|
|
341
|
-
# Treat passed forecast data lists
|
342
|
-
list_forecast_key = [
|
343
|
-
"pv_power_forecast",
|
344
|
-
"load_power_forecast",
|
345
|
-
"load_cost_forecast",
|
346
|
-
"prod_price_forecast",
|
347
|
-
"outdoor_temperature_forecast",
|
348
|
-
]
|
349
|
-
forecast_methods = [
|
350
|
-
"weather_forecast_method",
|
351
|
-
"load_forecast_method",
|
352
|
-
"load_cost_forecast_method",
|
353
|
-
"production_price_forecast_method",
|
354
|
-
"outdoor_temperature_forecast_method",
|
355
|
-
]
|
356
|
-
|
357
|
-
# Loop forecasts, check if value is a list and greater than or equal to forecast_dates
|
358
|
-
for method, forecast_key in enumerate(list_forecast_key):
|
359
|
-
if forecast_key in runtimeparams.keys():
|
360
|
-
if isinstance(runtimeparams[forecast_key], list) and len(
|
361
|
-
runtimeparams[forecast_key]
|
362
|
-
) >= len(forecast_dates):
|
363
|
-
params["passed_data"][forecast_key] = runtimeparams[forecast_key]
|
364
|
-
params["optim_conf"][forecast_methods[method]] = "list"
|
365
|
-
else:
|
366
|
-
logger.error(
|
367
|
-
f"ERROR: The passed data is either not a list or the length is not correct, length should be {str(len(forecast_dates))}"
|
368
|
-
)
|
369
|
-
logger.error(
|
370
|
-
f"Passed type is {str(type(runtimeparams[forecast_key]))} and length is {str(len(runtimeparams[forecast_key]))}"
|
371
|
-
)
|
372
|
-
# Check if string contains list, if so extract
|
373
|
-
if isinstance(runtimeparams[forecast_key], str):
|
374
|
-
if isinstance(ast.literal_eval(runtimeparams[forecast_key]), list):
|
375
|
-
runtimeparams[forecast_key] = ast.literal_eval(
|
376
|
-
runtimeparams[forecast_key]
|
377
|
-
)
|
378
|
-
list_non_digits = [
|
379
|
-
x
|
380
|
-
for x in runtimeparams[forecast_key]
|
381
|
-
if not (isinstance(x, int) or isinstance(x, float))
|
382
|
-
]
|
383
|
-
if len(list_non_digits) > 0:
|
384
|
-
logger.warning(
|
385
|
-
f"There are non numeric values on the passed data for {forecast_key}, check for missing values (nans, null, etc)"
|
386
|
-
)
|
387
|
-
for x in list_non_digits:
|
388
|
-
logger.warning(
|
389
|
-
f"This value in {forecast_key} was detected as non digits: {str(x)}"
|
390
|
-
)
|
391
|
-
else:
|
392
|
-
params["passed_data"][forecast_key] = None
|
393
|
-
|
394
341
|
# Add runtime exclusive (not in config) parameters to params
|
395
342
|
# regressor-model-fit
|
396
343
|
if set_type == "regressor-model-fit":
|
@@ -447,6 +394,16 @@ def treat_runtimeparams(
|
|
447
394
|
soc_final = runtimeparams["soc_final"]
|
448
395
|
params["passed_data"]["soc_final"] = soc_final
|
449
396
|
|
397
|
+
params["passed_data"]["operating_hours_of_each_deferrable_load"] = params[
|
398
|
+
"optim_conf"
|
399
|
+
].get("operating_hours_of_each_deferrable_load", None)
|
400
|
+
params["passed_data"]["start_timesteps_of_each_deferrable_load"] = params[
|
401
|
+
"optim_conf"
|
402
|
+
].get("start_timesteps_of_each_deferrable_load", None)
|
403
|
+
params["passed_data"]["end_timesteps_of_each_deferrable_load"] = params[
|
404
|
+
"optim_conf"
|
405
|
+
].get("end_timesteps_of_each_deferrable_load", None)
|
406
|
+
|
450
407
|
forecast_dates = copy.deepcopy(forecast_dates)[0:prediction_horizon]
|
451
408
|
|
452
409
|
# Load the default config
|
@@ -480,6 +437,59 @@ def treat_runtimeparams(
|
|
480
437
|
params["passed_data"]["soc_init"] = None
|
481
438
|
params["passed_data"]["soc_final"] = None
|
482
439
|
|
440
|
+
# Treat passed forecast data lists
|
441
|
+
list_forecast_key = [
|
442
|
+
"pv_power_forecast",
|
443
|
+
"load_power_forecast",
|
444
|
+
"load_cost_forecast",
|
445
|
+
"prod_price_forecast",
|
446
|
+
"outdoor_temperature_forecast",
|
447
|
+
]
|
448
|
+
forecast_methods = [
|
449
|
+
"weather_forecast_method",
|
450
|
+
"load_forecast_method",
|
451
|
+
"load_cost_forecast_method",
|
452
|
+
"production_price_forecast_method",
|
453
|
+
"outdoor_temperature_forecast_method",
|
454
|
+
]
|
455
|
+
|
456
|
+
# Loop forecasts, check if value is a list and greater than or equal to forecast_dates
|
457
|
+
for method, forecast_key in enumerate(list_forecast_key):
|
458
|
+
if forecast_key in runtimeparams.keys():
|
459
|
+
if isinstance(runtimeparams[forecast_key], list) and len(
|
460
|
+
runtimeparams[forecast_key]
|
461
|
+
) >= len(forecast_dates):
|
462
|
+
params["passed_data"][forecast_key] = runtimeparams[forecast_key]
|
463
|
+
params["optim_conf"][forecast_methods[method]] = "list"
|
464
|
+
else:
|
465
|
+
logger.error(
|
466
|
+
f"ERROR: The passed data is either not a list or the length is not correct, length should be {str(len(forecast_dates))}"
|
467
|
+
)
|
468
|
+
logger.error(
|
469
|
+
f"Passed type is {str(type(runtimeparams[forecast_key]))} and length is {str(len(runtimeparams[forecast_key]))}"
|
470
|
+
)
|
471
|
+
# Check if string contains list, if so extract
|
472
|
+
if isinstance(runtimeparams[forecast_key], str):
|
473
|
+
if isinstance(ast.literal_eval(runtimeparams[forecast_key]), list):
|
474
|
+
runtimeparams[forecast_key] = ast.literal_eval(
|
475
|
+
runtimeparams[forecast_key]
|
476
|
+
)
|
477
|
+
list_non_digits = [
|
478
|
+
x
|
479
|
+
for x in runtimeparams[forecast_key]
|
480
|
+
if not (isinstance(x, int) or isinstance(x, float))
|
481
|
+
]
|
482
|
+
if len(list_non_digits) > 0:
|
483
|
+
logger.warning(
|
484
|
+
f"There are non numeric values on the passed data for {forecast_key}, check for missing values (nans, null, etc)"
|
485
|
+
)
|
486
|
+
for x in list_non_digits:
|
487
|
+
logger.warning(
|
488
|
+
f"This value in {forecast_key} was detected as non digits: {str(x)}"
|
489
|
+
)
|
490
|
+
else:
|
491
|
+
params["passed_data"][forecast_key] = None
|
492
|
+
|
483
493
|
# Treat passed data for forecast model fit/predict/tune at runtime
|
484
494
|
if (
|
485
495
|
params["passed_data"].get("historic_days_to_retrieve", None) is not None
|
@@ -1091,7 +1101,7 @@ def build_secrets(
|
|
1091
1101
|
:type logger: logging.Logger
|
1092
1102
|
:param argument: dictionary of secrets arguments passed (url,key)
|
1093
1103
|
:type argument: dict
|
1094
|
-
:param options_path: path to the options file (options.json) (usually provided
|
1104
|
+
:param options_path: path to the options file (options.json) (usually provided by EMHASS-Add-on)
|
1095
1105
|
:type options_path: str
|
1096
1106
|
:param secrets_path: path to secrets file (secrets_emhass.yaml)
|
1097
1107
|
:type secrets_path: str
|
@@ -14,6 +14,7 @@ from pathlib import Path
|
|
14
14
|
|
15
15
|
import yaml
|
16
16
|
from flask import Flask, make_response, request
|
17
|
+
from flask import logging as log
|
17
18
|
from jinja2 import Environment, PackageLoader
|
18
19
|
from waitress import serve
|
19
20
|
|
@@ -384,7 +385,6 @@ def action_call(action_name):
|
|
384
385
|
|
385
386
|
ActionStr = " >> Setting input data dict"
|
386
387
|
app.logger.info(ActionStr)
|
387
|
-
app.logger.warning(costfun)
|
388
388
|
input_data_dict = set_input_data_dict(
|
389
389
|
emhass_conf, costfun, params, runtimeparams, action_name, app.logger
|
390
390
|
)
|
@@ -652,37 +652,30 @@ if __name__ == "__main__":
|
|
652
652
|
raise Exception("missing: " + str(emhass_conf["data_path"]))
|
653
653
|
|
654
654
|
# Define loggers
|
655
|
-
ch = logging.StreamHandler()
|
656
655
|
formatter = logging.Formatter(
|
657
656
|
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
658
657
|
)
|
659
|
-
|
658
|
+
log.default_handler.setFormatter(formatter)
|
660
659
|
# Action file logger
|
661
660
|
fileLogger = logging.FileHandler(str(emhass_conf["data_path"] / "actionLogs.txt"))
|
662
661
|
formatter = logging.Formatter("%(levelname)s - %(name)s - %(message)s")
|
663
662
|
fileLogger.setFormatter(formatter) # add format to Handler
|
664
663
|
if logging_level == "DEBUG":
|
665
664
|
app.logger.setLevel(logging.DEBUG)
|
666
|
-
ch.setLevel(logging.DEBUG)
|
667
665
|
fileLogger.setLevel(logging.DEBUG)
|
668
666
|
elif logging_level == "INFO":
|
669
667
|
app.logger.setLevel(logging.INFO)
|
670
|
-
ch.setLevel(logging.INFO)
|
671
668
|
fileLogger.setLevel(logging.INFO)
|
672
669
|
elif logging_level == "WARNING":
|
673
670
|
app.logger.setLevel(logging.WARNING)
|
674
|
-
ch.setLevel(logging.WARNING)
|
675
671
|
fileLogger.setLevel(logging.WARNING)
|
676
672
|
elif logging_level == "ERROR":
|
677
673
|
app.logger.setLevel(logging.ERROR)
|
678
|
-
ch.setLevel(logging.ERROR)
|
679
674
|
fileLogger.setLevel(logging.ERROR)
|
680
675
|
else:
|
681
676
|
app.logger.setLevel(logging.DEBUG)
|
682
|
-
ch.setLevel(logging.DEBUG)
|
683
677
|
fileLogger.setLevel(logging.DEBUG)
|
684
678
|
app.logger.propagate = False
|
685
|
-
app.logger.addHandler(ch)
|
686
679
|
app.logger.addHandler(fileLogger)
|
687
680
|
# Clear Action File logger file, ready for new instance
|
688
681
|
clearFileLog()
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|