mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 08:55:15 +00:00
Docs: Add global example documentation.
* merge_models: Use deecopy to not change input data.
This commit is contained in:
parent
c1dd31528b
commit
5bd8321e95
@ -879,3 +879,135 @@ Attributes:
|
|||||||
"utils": {}
|
"utils": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Full example Config
|
||||||
|
|
||||||
|
```{eval-rst}
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"general": {
|
||||||
|
"data_folder_path": null,
|
||||||
|
"data_output_subpath": "output",
|
||||||
|
"data_cache_subpath": "cache",
|
||||||
|
"latitude": 52.52,
|
||||||
|
"longitude": 13.405
|
||||||
|
},
|
||||||
|
"logging": {
|
||||||
|
"level": "INFO"
|
||||||
|
},
|
||||||
|
"devices": {
|
||||||
|
"batteries": [
|
||||||
|
{
|
||||||
|
"device_id": "battery1",
|
||||||
|
"hours": null,
|
||||||
|
"capacity_wh": 8000,
|
||||||
|
"charging_efficiency": 0.88,
|
||||||
|
"discharging_efficiency": 0.88,
|
||||||
|
"max_charge_power_w": 5000,
|
||||||
|
"initial_soc_percentage": 0,
|
||||||
|
"min_soc_percentage": 0,
|
||||||
|
"max_soc_percentage": 100
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inverters": [],
|
||||||
|
"home_appliances": []
|
||||||
|
},
|
||||||
|
"measurement": {
|
||||||
|
"load0_name": "Household",
|
||||||
|
"load1_name": null,
|
||||||
|
"load2_name": null,
|
||||||
|
"load3_name": null,
|
||||||
|
"load4_name": null
|
||||||
|
},
|
||||||
|
"optimization": {
|
||||||
|
"hours": 48,
|
||||||
|
"penalty": 10,
|
||||||
|
"ev_available_charge_rates_percent": [
|
||||||
|
0.0,
|
||||||
|
0.375,
|
||||||
|
0.5,
|
||||||
|
0.625,
|
||||||
|
0.75,
|
||||||
|
0.875,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prediction": {
|
||||||
|
"hours": 48,
|
||||||
|
"historic_hours": 48
|
||||||
|
},
|
||||||
|
"elecprice": {
|
||||||
|
"provider": "ElecPriceAkkudoktor",
|
||||||
|
"charges_kwh": 0.21,
|
||||||
|
"provider_settings": null
|
||||||
|
},
|
||||||
|
"load": {
|
||||||
|
"provider": "LoadAkkudoktor",
|
||||||
|
"provider_settings": null
|
||||||
|
},
|
||||||
|
"pvforecast": {
|
||||||
|
"provider": "PVForecastAkkudoktor",
|
||||||
|
"planes": [
|
||||||
|
{
|
||||||
|
"surface_tilt": 10.0,
|
||||||
|
"surface_azimuth": 10.0,
|
||||||
|
"userhorizon": [
|
||||||
|
10.0,
|
||||||
|
20.0,
|
||||||
|
30.0
|
||||||
|
],
|
||||||
|
"peakpower": 5.0,
|
||||||
|
"pvtechchoice": "crystSi",
|
||||||
|
"mountingplace": "free",
|
||||||
|
"loss": 14.0,
|
||||||
|
"trackingtype": 0,
|
||||||
|
"optimal_surface_tilt": false,
|
||||||
|
"optimalangles": false,
|
||||||
|
"albedo": null,
|
||||||
|
"module_model": null,
|
||||||
|
"inverter_model": null,
|
||||||
|
"inverter_paco": 6000,
|
||||||
|
"modules_per_string": 20,
|
||||||
|
"strings_per_inverter": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"surface_tilt": 20.0,
|
||||||
|
"surface_azimuth": 20.0,
|
||||||
|
"userhorizon": [
|
||||||
|
5.0,
|
||||||
|
15.0,
|
||||||
|
25.0
|
||||||
|
],
|
||||||
|
"peakpower": 3.5,
|
||||||
|
"pvtechchoice": "crystSi",
|
||||||
|
"mountingplace": "free",
|
||||||
|
"loss": 14.0,
|
||||||
|
"trackingtype": 1,
|
||||||
|
"optimal_surface_tilt": false,
|
||||||
|
"optimalangles": false,
|
||||||
|
"albedo": null,
|
||||||
|
"module_model": null,
|
||||||
|
"inverter_model": null,
|
||||||
|
"inverter_paco": 4000,
|
||||||
|
"modules_per_string": 20,
|
||||||
|
"strings_per_inverter": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"provider_settings": null
|
||||||
|
},
|
||||||
|
"weather": {
|
||||||
|
"provider": "WeatherImport",
|
||||||
|
"provider_settings": null
|
||||||
|
},
|
||||||
|
"server": {
|
||||||
|
"host": "0.0.0.0",
|
||||||
|
"port": 8503,
|
||||||
|
"verbose": false,
|
||||||
|
"startup_eosdash": true,
|
||||||
|
"eosdash_host": "0.0.0.0",
|
||||||
|
"eosdash_port": 8504
|
||||||
|
},
|
||||||
|
"utils": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -22,6 +22,8 @@ logger = get_logger(__name__)
|
|||||||
documented_types: set[PydanticBaseModel] = set()
|
documented_types: set[PydanticBaseModel] = set()
|
||||||
undocumented_types: dict[PydanticBaseModel, tuple[str, list[str]]] = dict()
|
undocumented_types: dict[PydanticBaseModel, tuple[str, list[str]]] = dict()
|
||||||
|
|
||||||
|
global_config_dict: dict[str, Any] = dict()
|
||||||
|
|
||||||
|
|
||||||
def get_title(config: PydanticBaseModel) -> str:
|
def get_title(config: PydanticBaseModel) -> str:
|
||||||
if config.__doc__ is None:
|
if config.__doc__ is None:
|
||||||
@ -209,8 +211,12 @@ def generate_config_table_md(
|
|||||||
table += ".. code-block:: json\n\n"
|
table += ".. code-block:: json\n\n"
|
||||||
if has_examples_list:
|
if has_examples_list:
|
||||||
input_dict = build_nested_structure(toplevel_keys[:-1], ins_dict_list)
|
input_dict = build_nested_structure(toplevel_keys[:-1], ins_dict_list)
|
||||||
|
if not extra_config:
|
||||||
|
global_config_dict[toplevel_keys[0]] = ins_dict_list
|
||||||
else:
|
else:
|
||||||
input_dict = build_nested_structure(toplevel_keys, ins_dict_list[0])
|
input_dict = build_nested_structure(toplevel_keys, ins_dict_list[0])
|
||||||
|
if not extra_config:
|
||||||
|
global_config_dict[toplevel_keys[0]] = ins_dict_list[0]
|
||||||
table += textwrap.indent(json.dumps(input_dict, indent=4), " ")
|
table += textwrap.indent(json.dumps(input_dict, indent=4), " ")
|
||||||
table += "\n"
|
table += "\n"
|
||||||
table += "```\n\n"
|
table += "```\n\n"
|
||||||
@ -258,6 +264,16 @@ def generate_config_md(config_eos: ConfigEOS) -> str:
|
|||||||
field_type, [field_name], f"EOS_{field_name.upper()}__", True
|
field_type, [field_name], f"EOS_{field_name.upper()}__", True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Full config
|
||||||
|
markdown += "## Full example Config\n\n"
|
||||||
|
markdown += "```{eval-rst}\n"
|
||||||
|
markdown += ".. code-block:: json\n\n"
|
||||||
|
# Test for valid config first
|
||||||
|
config_eos.merge_settings_from_dict(global_config_dict)
|
||||||
|
markdown += textwrap.indent(json.dumps(global_config_dict, indent=4), " ")
|
||||||
|
markdown += "\n"
|
||||||
|
markdown += "```\n\n"
|
||||||
|
|
||||||
# Assure there is no double \n at end of file
|
# Assure there is no double \n at end of file
|
||||||
markdown = markdown.rstrip("\n")
|
markdown = markdown.rstrip("\n")
|
||||||
markdown += "\n"
|
markdown += "\n"
|
||||||
@ -290,7 +306,8 @@ def main():
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error during Configuration Specification generation: {e}", file=sys.stderr)
|
print(f"Error during Configuration Specification generation: {e}", file=sys.stderr)
|
||||||
sys.exit(1)
|
# keep throwing error to debug potential problems (e.g. invalid examples)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -14,6 +14,7 @@ Key Features:
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
from copy import deepcopy
|
||||||
from typing import Any, Dict, List, Optional, Type, Union
|
from typing import Any, Dict, List, Optional, Type, Union
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ def merge_models(source: BaseModel, update_dict: dict[str, Any]) -> dict[str, An
|
|||||||
return update_dict
|
return update_dict
|
||||||
|
|
||||||
source_dict = source.model_dump(exclude_unset=True)
|
source_dict = source.model_dump(exclude_unset=True)
|
||||||
merged_dict = deep_update(source_dict, update_dict)
|
merged_dict = deep_update(source_dict, deepcopy(update_dict))
|
||||||
|
|
||||||
return merged_dict
|
return merged_dict
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user