openhems 0.3.2__tar.gz → 0.3.2.2__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.
Files changed (151) hide show
  1. {openhems-0.3.2 → openhems-0.3.2.2}/MANIFEST.in +1 -5
  2. {openhems-0.3.2/src/openhems.egg-info → openhems-0.3.2.2}/PKG-INFO +1 -1
  3. {openhems-0.3.2 → openhems-0.3.2.2}/pyproject.toml +3 -34
  4. openhems-0.3.2.2/src/openhems/data/openhems.schema.yaml +213 -0
  5. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/main.py +29 -6
  6. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/configuration_manager.py +4 -1
  7. openhems-0.3.2.2/src/openhems/modules/util/project_configuration.py +70 -0
  8. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/pages/02_Configuration.py +7 -5
  9. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/pages/04_About.py +6 -1
  10. {openhems-0.3.2 → openhems-0.3.2.2/src/openhems.egg-info}/PKG-INFO +1 -1
  11. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems.egg-info/SOURCES.txt +1 -0
  12. openhems-0.3.2/src/openhems/modules/util/project_configuration.py +0 -52
  13. {openhems-0.3.2 → openhems-0.3.2.2}/LICENSE +0 -0
  14. {openhems-0.3.2 → openhems-0.3.2.2}/emhass/config_emhass.yaml +0 -0
  15. {openhems-0.3.2 → openhems-0.3.2.2}/emhass/secrets_emhass.yaml +0 -0
  16. {openhems-0.3.2 → openhems-0.3.2.2}/readme.md +0 -0
  17. {openhems-0.3.2 → openhems-0.3.2.2}/setup.cfg +0 -0
  18. {openhems-0.3.2 → openhems-0.3.2.2}/setup.py +0 -0
  19. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/__init__.py +0 -0
  20. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/check_homeassistant_api.py +0 -0
  21. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/ennergy_supplier.yaml +0 -0
  22. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/keys_en.yaml +0 -0
  23. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/keys_fr.yaml +0 -0
  24. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/openhems_default.yaml +0 -0
  25. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/openhems_default_docker.yaml +0 -0
  26. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/openhems_tooltips_en.yaml +0 -0
  27. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/data/openhems_tooltips_fr.yaml +0 -0
  28. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/data_load_cost_forecast.csv +0 -0
  29. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/data_load_forecast.csv +0 -0
  30. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/data_prod_price_forecast.csv +0 -0
  31. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/data_weather_forecast.csv +0 -0
  32. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/heating_prediction.csv +0 -0
  33. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/long_train_data.pkl +0 -0
  34. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/opt_res_latest.csv +0 -0
  35. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/opt_res_perfect_optim_cost.csv +0 -0
  36. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/opt_res_perfect_optim_profit.csv +0 -0
  37. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/opt_res_perfect_optim_self-consumption.csv +0 -0
  38. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/test_df_final.pkl +0 -0
  39. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/test_response_get_data_get_method.pbz2 +0 -0
  40. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/test_response_openmeteo_get_method.pbz2 +0 -0
  41. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/test_response_scrapper_get_method.pbz2 +0 -0
  42. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/test_response_solarforecast_get_method.pbz2 +0 -0
  43. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/data/test_response_solcast_get_method.pbz2 +0 -0
  44. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/docs/conf.py +0 -0
  45. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/gunicorn.conf.py +0 -0
  46. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/options.json +0 -0
  47. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/load_clustering.py +0 -0
  48. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/load_forecast_sklearn.py +0 -0
  49. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/optim_results_analysis.py +0 -0
  50. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/read_csv_plot_data.py +0 -0
  51. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/save_pvlib_module_inverter_database.py +0 -0
  52. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/script_debug_forecasts.py +0 -0
  53. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/script_debug_optim.py +0 -0
  54. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/script_simple_thermal_model.py +0 -0
  55. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/script_thermal_model_optim.py +0 -0
  56. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/special_config_analysis.py +0 -0
  57. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/special_options.json +0 -0
  58. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/scripts/use_cases_analysis.py +0 -0
  59. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/__init__.py +0 -0
  60. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/command_line.py +0 -0
  61. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/data/config_defaults.json +0 -0
  62. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/forecast.py +0 -0
  63. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/machine_learning_forecaster.py +0 -0
  64. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/machine_learning_regressor.py +0 -0
  65. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/optimization.py +0 -0
  66. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/retrieve_hass.py +0 -0
  67. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/static/data/param_definitions.json +0 -0
  68. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/utils.py +0 -0
  69. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/src/emhass/web_server.py +0 -0
  70. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/__init__.py +0 -0
  71. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_command_line_utils.py +0 -0
  72. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_forecast.py +0 -0
  73. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_machine_learning_forecaster.py +0 -0
  74. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_machine_learning_regressor.py +0 -0
  75. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_optimization.py +0 -0
  76. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_retrieve_hass.py +0 -0
  77. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/emhass/tests/test_utils.py +0 -0
  78. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/__init__.py +0 -0
  79. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/contract/__init__.py +0 -0
  80. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/contract/contract.py +0 -0
  81. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/contract/generic_contract.py +0 -0
  82. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/contract/rte_contract.py +0 -0
  83. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/__init__.py +0 -0
  84. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/driver/emhass_adapter.py +0 -0
  85. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/emhass_strategy.py +0 -0
  86. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/energy_strategy.py +0 -0
  87. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/hybridinverter_strategy.py +0 -0
  88. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/offgrid_strategy.py +0 -0
  89. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/offpeak_strategy.py +0 -0
  90. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/optimization_algorithm.py +0 -0
  91. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/simulated_annealing_strategy.py +0 -0
  92. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/solarbased_strategy.py +0 -0
  93. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/solarnosell_strategy.py +0 -0
  94. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/sourceinverter_strategy.py +0 -0
  95. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/energy_strategy/switchoff_strategy.py +0 -0
  96. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/__init__.py +0 -0
  97. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/driver/domoticz_api.py +0 -0
  98. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/driver/fake_network.py +0 -0
  99. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/driver/home_assistant_api.py +0 -0
  100. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/feedback_switch.py +0 -0
  101. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/feeder.py +0 -0
  102. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/homestate_updater.py +0 -0
  103. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/inoutnode.py +0 -0
  104. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/network.py +0 -0
  105. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/node.py +0 -0
  106. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/outnode.py +0 -0
  107. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/network/schedule.py +0 -0
  108. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/__init__.py +0 -0
  109. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/cast_utility.py +0 -0
  110. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/json.py +0 -0
  111. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/logging.py +0 -0
  112. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/notification_manager.py +0 -0
  113. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/recorder.py +0 -0
  114. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/util/time.py +0 -0
  115. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/Dashboard.py +0 -0
  116. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/__init__.py +0 -0
  117. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/css/openhems.css +0 -0
  118. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/driver_vpn.py +0 -0
  119. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/alarm.svg +0 -0
  120. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/correct_32.ico +0 -0
  121. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/delete-20px.png +0 -0
  122. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/delete.png +0 -0
  123. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/favicon.ico +0 -0
  124. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/hourglass.svg +0 -0
  125. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/save_32.ico +0 -0
  126. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/img/wait.gif +0 -0
  127. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/js/params.js +0 -0
  128. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/pages/03_VPN.py +0 -0
  129. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/pages/__init__.py +0 -0
  130. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/templates/about.jinja2 +0 -0
  131. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/templates/panel.jinja2 +0 -0
  132. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/templates/params.framework.jinja2 +0 -0
  133. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/web_pyramid.py +0 -0
  134. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/modules/web/web_streamlit.py +0 -0
  135. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/server.py +0 -0
  136. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/server_vpn.py +0 -0
  137. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/unix_socket_action.py +0 -0
  138. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/unix_socket_client.py +0 -0
  139. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems/unix_socket_server.py +0 -0
  140. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems.egg-info/dependency_links.txt +0 -0
  141. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems.egg-info/requires.txt +0 -0
  142. {openhems-0.3.2 → openhems-0.3.2.2}/src/openhems.egg-info/top_level.txt +0 -0
  143. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_annealing_strategy.py +0 -0
  144. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_contract_module.py +0 -0
  145. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_emhass_adapter.py +0 -0
  146. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_feedbackswitch.py +0 -0
  147. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_offpeak_strategy.py +0 -0
  148. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_solarnosell_strategy.py +0 -0
  149. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_streamlit.py +0 -0
  150. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_streamlit_dashboard.py +0 -0
  151. {openhems-0.3.2 → openhems-0.3.2.2}/tests/test_util_module.py +0 -0
@@ -1,11 +1,7 @@
1
- graft data
2
- graft lib
3
-
4
- include_package_data data
1
+ include pyproject.toml
5
2
 
6
3
  recursive-include data *.yaml
7
4
  recursive-include emhass *
8
5
  global-exclude */__pycache__/*
9
6
  global-exclude *.pyc
10
7
 
11
- include pyproject.toml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhems
3
- Version: 0.3.2
3
+ Version: 0.3.2.2
4
4
  Summary: A sample Home Energy Managment System based on Home-Assistant
5
5
  Home-page: https://github.com/abriotde/openhems-sample.git
6
6
  Author: OpenHomeSystem
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openhems"
3
- version = "0.3.2"
3
+ version = "0.3.2.2"
4
4
  dynamic = [
5
5
  # "version" # , "description"
6
6
  ]
@@ -69,18 +69,9 @@ Homepage = "https://openhomesystem.com"
69
69
  Issues = "https://github.com/abriotde/openhems-sample/issues"
70
70
  Documentation = "https://openhems.readthedocs.io/en/latest/"
71
71
  Repository = "https://github.com/abriotde/openhems-sample.git"
72
-
72
+
73
73
  [build-system]
74
- requires = [
75
- 'requests', "pandas", "pyyaml", 'packaging', 'astral',
76
- 'GitPython', 'toml', 'scikit-opt',
77
- # For EMHASS
78
- 'numpy', 'plotly', 'scikit-learn', 'skforecast', 'pvlib', 'beautifulsoup4' , 'protobuf',
79
- 'pandas', 'scipy', 'h5py', 'pulp',
80
- 'flit_core >=3.2,<4', "setuptools>=42", "wheel"
81
- ]
82
- # build-backend = "flit_core.buildapi"
83
- # build-backend = "openhems.build"
74
+ requires = ["setuptools>=61.0", "wheel"]
84
75
  build-backend = "setuptools.build_meta"
85
76
 
86
77
  [tool.pytest.ini_options]
@@ -116,10 +107,6 @@ ignore_errors = true
116
107
  [tool.coverage.html]
117
108
  directory = "coverage_html_report"
118
109
 
119
-
120
- [tool.setuptools.data-files]
121
- # "share/openhems" = ["data/*.yaml"]
122
-
123
110
  [tool.setuptools]
124
111
  include-package-data = true
125
112
 
@@ -140,24 +127,6 @@ openhems = [
140
127
  "emhass/scripts/*.json",
141
128
  "emhass/src/emhass/static/data/*.json",
142
129
  "emhass/src/emhass/data/*.json",
143
- "pyproject.toml"
144
- ]
145
-
146
- [tool.flit.sdist]
147
- include = [
148
- "LICENSE",
149
- "CHANGELOG.md",
150
- # Documentation
151
- "doc/",
152
- # "CODE_OF_CONDUCT.rst", # used as an include in the Documentation
153
- # "EXAMPLES.rst", # used as an include in the Documentation
154
- # Tests
155
- "tests/",
156
- # "tox.ini",
157
- # Utilities
158
- "data/",
159
- "lib/",
160
- # "babel.cfg",
161
130
  ]
162
131
 
163
132
  [dependency-groups]
@@ -0,0 +1,213 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "OpenHEMS Configuration Schema",
4
+ "description": "Schéma de validation pour openhems.yaml",
5
+ "type": "object",
6
+ "properties": {
7
+ "api": {
8
+ "type": "object",
9
+ "properties": {
10
+ "url": {
11
+ "type": "string",
12
+ "format": "uri",
13
+ "description": "URL de l'API Home Assistant (ex: http://...:8123/api)"
14
+ },
15
+ "long_lived_token": {
16
+ "type": "string",
17
+ "description": "Token d'accès permanent Home Assistant"
18
+ },
19
+ "ssl_certificate": {
20
+ "type": "string",
21
+ "description": "Chemin ou contenu du certificat SSL (optionnel)"
22
+ }
23
+ },
24
+ "required": ["url", "long_lived_token"],
25
+ "additionalProperties": false
26
+ },
27
+ "localization": {
28
+ "type": "object",
29
+ "properties": {
30
+ "latitude": {
31
+ "type": "number",
32
+ "minimum": -90,
33
+ "maximum": 90,
34
+ "description": "Latitude en degrés décimaux"
35
+ },
36
+ "longitude": {
37
+ "type": "number",
38
+ "minimum": -180,
39
+ "maximum": 180,
40
+ "description": "Longitude en degrés décimaux"
41
+ },
42
+ "altitude": {
43
+ "type": "integer",
44
+ "description": "Altitude en mètres (optionnel)"
45
+ },
46
+ "timeZone": {
47
+ "type": "string",
48
+ "description": "Fuseau horaire (ex: Europe/Paris)"
49
+ }
50
+ },
51
+ "required": ["latitude", "longitude", "timeZone"],
52
+ "additionalProperties": false
53
+ },
54
+ "server": {
55
+ "type": "object",
56
+ "properties": {
57
+ "loglevel": {
58
+ "type": "string",
59
+ "enum": ["debug", "info", "warning", "error", "critical"],
60
+ "default": "info",
61
+ "description": "Niveau de journalisation"
62
+ },
63
+ "loopDelay": {
64
+ "type": "integer",
65
+ "minimum": 1,
66
+ "default": 30,
67
+ "description": "Délai entre les cycles d'optimisation (secondes)"
68
+ },
69
+ "network": {
70
+ "type": "string",
71
+ "enum": ["homeassistant", "local", "mqtt"],
72
+ "default": "homeassistant",
73
+ "description": "Type d'API réseau utilisée"
74
+ },
75
+ "strategies": {
76
+ "type": "array",
77
+ "description": "Liste des stratégies actives",
78
+ "items": {
79
+ "type": "object",
80
+ "properties": {
81
+ "class": {
82
+ "type": "string",
83
+ "description": "Nom de la classe de stratégie (ex: offpeak, self_consumption)"
84
+ },
85
+ "id": {
86
+ "type": "string",
87
+ "description": "Identifiant unique de la stratégie"
88
+ }
89
+ },
90
+ "required": ["class", "id"],
91
+ "additionalProperties": false
92
+ }
93
+ }
94
+ },
95
+ "required": ["loopDelay", "network"],
96
+ "additionalProperties": false
97
+ },
98
+ "network": {
99
+ "type": "object",
100
+ "properties": {
101
+ "nodes": {
102
+ "type": "array",
103
+ "description": "Liste des nœuds (équipements, sources, charges)",
104
+ "items": {
105
+ "type": "object",
106
+ "properties": {
107
+ "id": {
108
+ "type": "string",
109
+ "description": "Identifiant unique du nœud"
110
+ },
111
+ "class": {
112
+ "type": "string",
113
+ "enum": ["PublicPowerGrid", "switch", "battery", "pv", "heater", "ev"],
114
+ "description": "Type de nœud"
115
+ },
116
+ "strategy": {
117
+ "type": "string",
118
+ "description": "Référence à une stratégie (optionnelle)"
119
+ },
120
+ "currentPower": {
121
+ "type": "string",
122
+ "description": "Entité Home Assistant pour la puissance instantanée"
123
+ },
124
+ "maxPower": {
125
+ "type": "number",
126
+ "description": "Puissance maximale (W)"
127
+ },
128
+ "minPower": {
129
+ "type": "number",
130
+ "description": "Puissance minimale (W)"
131
+ },
132
+ "powerMargin": {
133
+ "type": "number",
134
+ "description": "Marge de puissance (W) – pour le réseau public"
135
+ },
136
+ "isOn": {
137
+ "type": "string",
138
+ "description": "Entité Home Assistant pour l'état marche/arrêt (pour les commutateurs)"
139
+ },
140
+ "constraints": {
141
+ "type": "object",
142
+ "properties": {
143
+ "minPower": {
144
+ "type": "number",
145
+ "description": "Puissance minimale admissible (W)"
146
+ },
147
+ "minPowerDelay": {
148
+ "type": "integer",
149
+ "description": "Durée minimale de maintien de minPower (secondes)"
150
+ }
151
+ },
152
+ "additionalProperties": false
153
+ },
154
+ "contract": {
155
+ "type": "object",
156
+ "description": "Contrat d'électricité (pour PublicPowerGrid)",
157
+ "properties": {
158
+ "class": {
159
+ "type": "string",
160
+ "enum": ["RTETempo", "Base", "HeuresCreuses"],
161
+ "description": "Type de contrat"
162
+ },
163
+ "color": {
164
+ "type": "string",
165
+ "description": "Entité HA pour la couleur Tempo (bleu/blanc/rouge)"
166
+ },
167
+ "nextcolor": {
168
+ "type": "string",
169
+ "description": "Entité HA pour la couleur du lendemain"
170
+ },
171
+ "offpeakhoursranges": {
172
+ "type": "array",
173
+ "items": {
174
+ "type": "string",
175
+ "pattern": "^\\d{1,2}:|h(\\d{1,2})?\\s*-\\s*\\d{1,2}(:|h)(\\d{1,2})?$",
176
+ "description": "Plage horaire ex: '22h05 - 6h'"
177
+ },
178
+ "description": "Plages heures creuses"
179
+ }
180
+ },
181
+ "required": ["class"],
182
+ "additionalProperties": false
183
+ }
184
+ },
185
+ "required": ["id", "class", "currentPower", "maxPower"],
186
+ "allOf": [
187
+ {
188
+ "if": {
189
+ "properties": { "class": { "const": "PublicPowerGrid" } }
190
+ },
191
+ "then": {
192
+ "required": ["powerMargin", "contract"]
193
+ }
194
+ },
195
+ {
196
+ "if": {
197
+ "properties": { "class": { "const": "switch" } }
198
+ },
199
+ "then": {
200
+ "required": ["isOn"]
201
+ }
202
+ }
203
+ ]
204
+ }
205
+ }
206
+ },
207
+ "required": ["nodes"],
208
+ "additionalProperties": false
209
+ }
210
+ },
211
+ "required": ["api", "localization", "server", "network"],
212
+ "additionalProperties": false
213
+ }
@@ -10,8 +10,11 @@ import sys
10
10
  import logging
11
11
  from threading import Thread
12
12
  import argparse
13
+ import threading
13
14
  import traceback
14
15
  from pathlib import Path
16
+
17
+ from openhems.modules.util.project_configuration import ProjectConfiguration
15
18
  openhemsPath = Path(__file__).parents[1]
16
19
  sys.path.append(str(openhemsPath))
17
20
  # pylint: disable=wrong-import-position
@@ -120,20 +123,37 @@ class OpenHEMSApplication:
120
123
  self.logger.info("OpenHEMS loaded.")
121
124
  network.notify("Start OpenHEMS.")
122
125
 
123
- def runManagementServer(self):
126
+ def runManagementServer(self, event:threading.Event=None):
124
127
  """
125
128
  Run core server (Smart part) without the webserver part.
126
129
  """
130
+
127
131
  if self.server is not None:
132
+ schedule = self.server.getSchedule()
133
+ network = self.server.getNetwork()
134
+ else: # Create a UnixSocketServer even if there is no core server.
135
+ # In order to allow webserver to start and display error messages / reconfigure server.
136
+ schedule = {}
137
+ network = FakeNetwork(ProjectConfiguration())
138
+ try:
128
139
  socket = UnixSocketServer(
129
- self.server.getSchedule(),
130
- self.server.getNetwork(),
140
+ schedule,
141
+ network,
131
142
  socket_path=self.configurator.get("server.socketpath"),
132
143
  logger=self.logger
133
144
  )
134
145
  socket.start()
146
+ except Exception as e: # pylint: disable=broad-exception-caught
147
+ self.logger.error("Error occurred while starting management server: %s", e)
148
+ if event:
149
+ event.set()
150
+
151
+ if self.server is not None:
135
152
  # server.run() is infinite loop (never give hand back)
136
- self.server.run()
153
+ try:
154
+ self.server.run()
155
+ except Exception as e: # pylint: disable=broad-exception-caught
156
+ self.logger.error("Error occurred while running management server: %s", e)
137
157
  else:
138
158
  self.logger.error(
139
159
  "Core server cannot start because of "
@@ -150,10 +170,13 @@ class OpenHEMSApplication:
150
170
  """
151
171
  Run wall OpenHEMS Application
152
172
  """
173
+ event = threading.Event()
174
+ t1 = Thread(target=self.runManagementServer, args=[event])
175
+ t1.start()
176
+ # Wait UnixSocketServer started (before web server try listen to it)
177
+ event.wait()
153
178
  t0 = Thread(target=self.runWebServer, args=[])
154
179
  t0.start()
155
- t1 = Thread(target=self.runManagementServer, args=[])
156
- t1.start()
157
180
  # t.join()
158
181
  # t.run()
159
182
 
@@ -182,7 +182,10 @@ class ConfigurationManager():
182
182
  if dictConfig is not None:
183
183
  self._load(dictConfig, init)
184
184
  self._cache = {}
185
- self.filepaths.append(yamlConfig)
185
+ if isinstance(yamlConfig, str):
186
+ yamlConfig = Path(yamlConfig)
187
+ absPath = yamlConfig.resolve()
188
+ self.filepaths.append(absPath)
186
189
  # print(self._conf)
187
190
 
188
191
  def add(self, key, value, init=False, prekey=''):
@@ -0,0 +1,70 @@
1
+ """
2
+ Usefull to get informations from pyproject.toml
3
+ """
4
+
5
+ from pathlib import Path
6
+ import toml # pylint: disable=E0401
7
+ ROOT_DIR = Path(__file__).parents[2]
8
+ # In your openhems/__init__.py
9
+ from importlib.metadata import version, metadata
10
+
11
+ __version__ = version("openhems")
12
+ # or read other metadata:
13
+ name = metadata("openhems")["Name"]
14
+ class ProjectConfiguration:
15
+ """
16
+ Usefull function to do something like a cast : Convertion of types
17
+ """
18
+
19
+ def __init__(self, openHemsProjectConfPath=None):
20
+ # In your openhems/__init__.py
21
+ self._version = version("openhems")
22
+ self._conf = metadata("openhems")
23
+
24
+ def getVersion(self):
25
+ """
26
+ Return current project version.
27
+ """
28
+ return self._version
29
+
30
+ def getMaintainers(self):
31
+ """
32
+ Return current project maintainers.
33
+ """
34
+ print("Project configuration:", self._conf)
35
+ return self._conf.get('Maintainer', 'Unknown')
36
+
37
+ def getUrls(self):
38
+ """
39
+ get projects urls
40
+ """
41
+ url_entries = self._conf.get_all('Project-URL')
42
+ all_urls = {}
43
+ for entry in url_entries:
44
+ label, url = entry.split(", ", 1)
45
+ all_urls[label] = url
46
+ return all_urls
47
+
48
+ def getConf(self):
49
+ """
50
+ get all configurations
51
+ """
52
+ return self._conf
53
+
54
+ def getLicence(self):
55
+ """
56
+ Get Licence
57
+ """
58
+ return "GPL-3.0-or-later"
59
+
60
+ def getContact(self):
61
+ """
62
+ Get contact information
63
+ """
64
+ return self._conf.get('Maintainer-email', 'Unknown')
65
+
66
+ def getName(self):
67
+ """
68
+ Get project name
69
+ """
70
+ return self._conf['Name']
@@ -19,8 +19,8 @@ from openhems.modules.util.json import json_default
19
19
  from openhems.modules.web.web_streamlit import get_logger
20
20
 
21
21
  # pylint: disable=wrong-import-position
22
- ROOT_PATH = Path(__file__).parents[5]
23
- sys.path.append(str(ROOT_PATH / "src"))
22
+ ROOT_PATH = Path(__file__).parents[4]
23
+ sys.path.append(str(ROOT_PATH))
24
24
  from openhems.modules.web import OpenhemsHTTPServer
25
25
  # from openhems.modules.util import (
26
26
  # ConfigurationManager, ConfigurationException, CastUtililty, CastException, ProjectConfiguration
@@ -75,7 +75,7 @@ def load_schema():
75
75
  """
76
76
  Load the schema for OpenHEMS configuration validation.
77
77
  """
78
- with open(str(ROOT_PATH / "config/openhems.schema.yaml"), "r", encoding="utf-8") as f:
78
+ with open(str(ROOT_PATH / "openhems/data/openhems.schema.yaml"), "r", encoding="utf-8") as f:
79
79
  return yaml.safe_load(f)
80
80
 
81
81
  def validate_config(config:dict|str, schema=None):
@@ -112,7 +112,7 @@ def snake_case(s):
112
112
 
113
113
  def save_basic_config(
114
114
  basic_config: BasicConfiguration,
115
- config_page=ROOT_PATH / "config/openhems.yaml"):
115
+ config_page=ROOT_PATH / "../config/openhems.yaml"):
116
116
  """
117
117
  Convert the basic configuration and merge it
118
118
  to OpenHEMS configuration file and then save it.
@@ -483,7 +483,7 @@ def basic_configure_supplier():
483
483
  Display the electricity supplier configuration page.
484
484
  """
485
485
  st.write("**Quel est votre fournisseur d'électricité ?**")
486
- contracts = load_config(str(ROOT_PATH / "src/openhems/data/ennergy_supplier.yaml"))
486
+ contracts = load_config(str(ROOT_PATH / "openhems/data/ennergy_supplier.yaml"))
487
487
  suppliers_dict = get_suplliers_dict(contracts)
488
488
  contract = st.session_state.config.contract
489
489
  supplier_key = basic_configure_supplier_select(suppliers_dict, contract)
@@ -693,6 +693,8 @@ def configure_page():
693
693
  configurator_path = st.session_state.configurator_path
694
694
  with open(configurator_path, "r", encoding="utf-8") as f1:
695
695
  conf = yaml.safe_load(f1)
696
+ if conf is None:
697
+ conf = {}
696
698
  has_nodes = len(conf.get("network", {}).get("nodes", [])) != 0
697
699
  if "config_ui_editor" in st.session_state:
698
700
  edition_state = st.session_state.config_ui_editor
@@ -18,7 +18,12 @@ def about_page():
18
18
  st.markdown(f"""
19
19
  **{conf.getName()}** version {conf.getVersion()}
20
20
  Licence : {conf.getLicence()}
21
- [Site web]({conf.getUrls()['Homepage']}) | [Documentation]({conf.getUrls()['Documentation']})
21
+ [Site web]({conf.getUrls().get('Homepage', '#')}) | [Documentation]({conf.getUrls().get('Documentation', '#')})
22
+ [Source code]({conf.getUrls().get('Repository', '#')}) | [Bug tracker]({conf.getUrls().get('Issues', '#')})
23
+ Contact : {conf.getContact()}
24
+
25
+ N'hésitez pas à contribuer au projet sur [GitHub]({conf.getUrls().get('Source', '#')})
22
26
  """)
27
+ # Merci à tous les contributeurs qui ont participé au développement d'OpenHEMS :
23
28
 
24
29
  about_page()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhems
3
- Version: 0.3.2
3
+ Version: 0.3.2.2
4
4
  Summary: A sample Home Energy Managment System based on Home-Assistant
5
5
  Home-page: https://github.com/abriotde/openhems-sample.git
6
6
  Author: OpenHomeSystem
@@ -22,6 +22,7 @@ src/openhems.egg-info/top_level.txt
22
22
  src/openhems/data/ennergy_supplier.yaml
23
23
  src/openhems/data/keys_en.yaml
24
24
  src/openhems/data/keys_fr.yaml
25
+ src/openhems/data/openhems.schema.yaml
25
26
  src/openhems/data/openhems_default.yaml
26
27
  src/openhems/data/openhems_default_docker.yaml
27
28
  src/openhems/data/openhems_tooltips_en.yaml
@@ -1,52 +0,0 @@
1
- """
2
- Usefull to get informations from pyproject.toml
3
- """
4
-
5
- from pathlib import Path
6
- import toml # pylint: disable=E0401
7
-
8
-
9
- class ProjectConfiguration:
10
- """
11
- Usefull function to do something like a cast : Convertion of types
12
- """
13
-
14
- def __init__(self, openHemsProjectConfPath=None):
15
- if openHemsProjectConfPath is None:
16
- # openHemsProjectConfPath = Path(__file__).parents[4] / "pyproject.toml"
17
- for path in Path(__file__).parents:
18
- openHemsProjectConfPath = path / "pyproject.toml"
19
- if openHemsProjectConfPath.is_file():
20
- break
21
- with openHemsProjectConfPath.open('r', encoding="utf-8") as file:
22
- self._conf = toml.loads(file.read())
23
-
24
- def getVersion(self):
25
- """
26
- Return current project version.
27
- """
28
- return self._conf['project']['version']
29
-
30
- def getMaintainers(self):
31
- """
32
- Return current project maintainers.
33
- """
34
- return self._conf['project']['maintainers']
35
-
36
- def getUrls(self):
37
- """
38
- get projects urls
39
- """
40
- return self._conf['project']['urls']
41
-
42
- def getLicence(self):
43
- """
44
- Get Licence
45
- """
46
- return "GPL-3.0-or-later"
47
-
48
- def getName(self):
49
- """
50
- Get project name
51
- """
52
- return "OpenHEMS"
File without changes
File without changes
File without changes
File without changes