mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-11-13 01:03:45 +01:00
A battery profile describes a battery model: the charge and discharge limit
maps over temperature and SoC, the charge and discharge efficiency curves
over C-rate, the technical SoC bounds, the hard temperature cutoffs and,
for a model, its nominal capacity and power limits. EOS packages the
generic profile generic-lfp; users add their own profiles.
A battery or electric vehicle selects its profile by battery_profile and
describes how the installation differs from it in profile_adjustment
(capacity, power limits of the installation, periodic full charge). The
effective values are resolved from both at the measured operating point
(temperature, SoC, power) and shown as effective_* fields.
The GENETIC simulation uses the limits and efficiencies of the profile over
SoC, with precomputed tables as a fast path; GENETIC0 gets the values at the
operating point. Optimization parameters are always valid: a battery whose
profile is missing, unreadable or invalid uses the packaged generic-lfp
profile, and the former defaults only if that is not usable either; each is
logged as error, and an optimization run is never cancelled because of a
battery.
Additional changes
- Add a generic device profile store: user and packaged profiles, atomic
saves, compiled profiles cached per file and checked again at most once a
second, plain file names as profile names ('schema' is reserved). On
Windows, a save or read that collides with the other is retried briefly.
- Add the REST API /v1/profile to list the profile kinds and to list, read
(document and JSON schema), save and delete profiles.
- Check the hard temperature cutoffs on the exact temperature.
- Resolve inhibited charging or discharging to a power of 0, e.g. for a cold
battery; give GENETIC0 its own discharge limit for that.
- Limit generic profiles without own power limits to the former 5000 W.
- Accept only the implemented units; current limits need the nominal
voltage.
- Migrate legacy battery settings into the profile adjustment, keep the
former charge power limit as discharge limit (also for a Home Assistant
entity on it) and report dropped efficiencies as errors.
- Limit GENETIC battery discharge by the discharge power.
- Allow battery profile lookups while the configuration is created.
- Resolve a battery once per configuration dump.
- Package the bundled profiles, document battery profiles and regenerate
the configuration and OpenAPI documentation.
- Ignore the report PDFs written by the visualization tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Assisted-by: Claude Code (claude-opus-5-5)
8.9 KiB
8.9 KiB
Adapter Configuration
:::{table} adapter :widths: 10 20 10 5 5 30 :align: left
| Name | Environment Variable | Type | Read-Only | Default | Description |
|---|---|---|---|---|---|
| homeassistant | EOS_ADAPTER__HOMEASSISTANT |
HomeAssistantAdapterCommonSettings |
rw |
required |
Home Assistant adapter settings. |
| nodered | EOS_ADAPTER__NODERED |
NodeREDAdapterCommonSettings |
rw |
required |
NodeRED adapter settings. |
| provider | EOS_ADAPTER__PROVIDER |
Optional[list[str]] |
rw |
None |
List of adapter provider id(s) of provider(s) to be used. |
| providers | list[str] |
ro |
N/A |
Available adapter provider ids. | |
| ::: |
Example Input
{
"adapter": {
"provider": [
"HomeAssistant"
],
"homeassistant": {
"config_entity_ids": null,
"load_emr_entity_ids": null,
"grid_export_emr_entity_ids": null,
"grid_import_emr_entity_ids": null,
"pv_production_emr_entity_ids": null,
"device_measurement_entity_ids": null,
"device_instruction_entity_ids": null,
"solution_entity_ids": null
},
"nodered": {
"host": "127.0.0.1",
"port": 1880
}
}
}
Example Output
{
"adapter": {
"provider": [
"HomeAssistant"
],
"homeassistant": {
"config_entity_ids": null,
"load_emr_entity_ids": null,
"grid_export_emr_entity_ids": null,
"grid_import_emr_entity_ids": null,
"pv_production_emr_entity_ids": null,
"device_measurement_entity_ids": null,
"device_instruction_entity_ids": null,
"solution_entity_ids": null,
"homeassistant_entity_ids": [],
"eos_solution_entity_ids": [],
"eos_device_instruction_entity_ids": []
},
"nodered": {
"host": "127.0.0.1",
"port": 1880
},
"providers": [
"HomeAssistant",
"NodeRED"
]
}
}
Common settings for the NodeRED adapter
The Node-RED adapter sends to HTTP IN nodes.
This is the example flow:
[HTTP In <URL>] -> [Function (parse payload)] -> [Debug] -> [HTTP Response]
There are two URLs that are used:
- GET /eos/data_aquisition The GET is issued before the optimization.
- POST /eos/control_dispatch The POST is issued after the optimization.
:::{table} adapter::nodered :widths: 10 10 5 5 30 :align: left
| Name | Type | Read-Only | Default | Description |
|---|---|---|---|---|
| host | Optional[str] |
rw |
127.0.0.1 |
Node-RED server IP address. Defaults to 127.0.0.1. |
| port | Optional[int] |
rw |
1880 |
Node-RED server IP port number. Defaults to 1880. |
| ::: |
Example Input/Output
{
"adapter": {
"nodered": {
"host": "127.0.0.1",
"port": 1880
}
}
}
Common settings for the home assistant adapter
:::{table} adapter::homeassistant :widths: 10 10 5 5 30 :align: left
| Name | Type | Read-Only | Default | Description |
|---|---|---|---|---|
| config_entity_ids | Optional[dict[str, str]] |
rw |
None |
Mapping of EOS config keys to Home Assistant entity IDs. |
| The config key has to be given by a ‘/’-separated path | ||||
| e.g. devices/batteries/battery1/profile_adjustment/nominal_capacity_wh | ||||
| Devices are addressed by their device_id. The setting must exist. | ||||
| device_instruction_entity_ids | Optional[list[str]] |
rw |
None |
Entity IDs for device (resource) instructions to be updated by EOS. |
| The device ids (resource ids) have to be prepended by 'sensor.eos_' to build the entity_id. | ||||
| E.g. The instruction for device id 'battery1' becomes the entity_id 'sensor.eos_battery1'. | ||||
| device_measurement_entity_ids | Optional[dict[str, str]] |
rw |
None |
Mapping of EOS device measurement keys to Home Assistant entity IDs. Registered keys such as 'battery1-soc-factor' are accepted; legacy underscore spellings are resolved when they uniquely match a registered key. |
| eos_device_instruction_entity_ids | list[str] |
ro |
N/A |
Entity IDs for energy management instructions available at EOS. |
| eos_solution_entity_ids | list[str] |
ro |
N/A |
Entity IDs for optimization solution available at EOS. |
| grid_export_emr_entity_ids | Optional[list[str]] |
rw |
None |
Entity ID(s) of export to grid energy meter readings [kWh] |
| grid_import_emr_entity_ids | Optional[list[str]] |
rw |
None |
Entity ID(s) of import from grid energy meter readings [kWh] |
| homeassistant_entity_ids | list[str] |
ro |
N/A |
Entity IDs available at Home Assistant. |
| load_emr_entity_ids | Optional[list[str]] |
rw |
None |
Entity ID(s) of load energy meter readings [kWh] |
| pv_production_emr_entity_ids | Optional[list[str]] |
rw |
None |
Entity ID(s) of PV production energy meter readings [kWh] |
| solution_entity_ids | Optional[list[str]] |
rw |
None |
Entity IDs for optimization solution keys to be updated by EOS. |
| The solution keys have to be prepended by 'sensor.eos_' to build the entity_id. | ||||
| E.g. solution key 'battery1_idle_op_mode' becomes the entity_id 'sensor.eos_battery1_idle_op_mode'. | ||||
| ::: |
Example Input
{
"adapter": {
"homeassistant": {
"config_entity_ids": {
"devices/batteries/battery1/profile_adjustment/nominal_capacity_wh": "sensor.battery1_capacity"
},
"load_emr_entity_ids": [
"sensor.load_energy_total_kwh"
],
"grid_export_emr_entity_ids": [
"sensor.grid_export_energy_total_kwh"
],
"grid_import_emr_entity_ids": [
"sensor.grid_import_energy_total_kwh"
],
"pv_production_emr_entity_ids": [
"sensor.pv_energy_total_kwh"
],
"device_measurement_entity_ids": {
"ev11-soc-factor": "sensor.ev11_soc_factor",
"battery1-soc-factor": "sensor.battery1_soc_factor"
},
"device_instruction_entity_ids": [
"sensor.eos_battery1"
],
"solution_entity_ids": [
"sensor.eos_battery1_idle_mode_mode"
]
}
}
}
Example Output
{
"adapter": {
"homeassistant": {
"config_entity_ids": {
"devices/batteries/battery1/profile_adjustment/nominal_capacity_wh": "sensor.battery1_capacity"
},
"load_emr_entity_ids": [
"sensor.load_energy_total_kwh"
],
"grid_export_emr_entity_ids": [
"sensor.grid_export_energy_total_kwh"
],
"grid_import_emr_entity_ids": [
"sensor.grid_import_energy_total_kwh"
],
"pv_production_emr_entity_ids": [
"sensor.pv_energy_total_kwh"
],
"device_measurement_entity_ids": {
"ev11-soc-factor": "sensor.ev11_soc_factor",
"battery1-soc-factor": "sensor.battery1_soc_factor"
},
"device_instruction_entity_ids": [
"sensor.eos_battery1"
],
"solution_entity_ids": [
"sensor.eos_battery1_idle_mode_mode"
],
"homeassistant_entity_ids": [],
"eos_solution_entity_ids": [],
"eos_device_instruction_entity_ids": []
}
}
}